Merge "Introduce separate log action for deleting pages on move"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 25 Nov 2016 02:52:28 +0000 (02:52 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 25 Nov 2016 02:52:28 +0000 (02:52 +0000)
1  2 
includes/DefaultSettings.php
includes/page/WikiPage.php
languages/i18n/en.json
languages/i18n/qqq.json

@@@ -1586,7 -1586,7 +1586,7 @@@ $wgEnableUserEmail = true
  
  /**
   * Set to true to put the sending user's email in a Reply-To header
 - * instead of From. ($wgEmergencyContact will be used as From.)
 + * instead of From. ($wgPasswordSender will be used as From.)
   *
   * Some mailers (eg SMTP) set the SMTP envelope sender to the From value,
   * which can cause problems with SPF validation and leak recipient addresses
@@@ -5864,7 -5864,7 +5864,7 @@@ $wgProxyList = []
  /**
   * Default cookie lifetime, in seconds. Setting to 0 makes all cookies session-only.
   */
 -$wgCookieExpiration = 180 * 86400;
 +$wgCookieExpiration = 30 * 86400;
  
  /**
   * Default login cookie lifetime, in seconds. Setting
   * calculate the cookie lifetime. As with $wgCookieExpiration, 0 will make
   * login cookies session-only.
   */
 -$wgExtendedLoginCookieExpiration = null;
 +$wgExtendedLoginCookieExpiration = 180 * 86400;
  
  /**
   * Set to set an explicit domain on the login cookies eg, "justthis.domain.org"
@@@ -5926,12 -5926,6 +5926,12 @@@ $wgCacheVaryCookies = []
   */
  $wgSessionName = false;
  
 +/**
 + * Whether to set a cookie when a user is autoblocked. Doing so means that a blocked user, even
 + * after logging out and moving to a new IP address, will still be blocked.
 + */
 +$wgCookieSetOnAutoblock = false;
 +
  /** @} */ # end of cookie settings }
  
  /************************************************************************//**
@@@ -7516,6 -7510,7 +7516,7 @@@ $wgLogActionsHandlers = 
        'contentmodel/change' => 'ContentModelLogFormatter',
        'contentmodel/new' => 'ContentModelLogFormatter',
        'delete/delete' => 'DeleteLogFormatter',
+       'delete/delete_redir' => 'DeleteLogFormatter',
        'delete/event' => 'DeleteLogFormatter',
        'delete/restore' => 'DeleteLogFormatter',
        'delete/revision' => 'DeleteLogFormatter',
@@@ -7567,6 -7562,7 +7568,7 @@@ $wgActionFilteredLogs = 
        ],
        'delete' => [
                'delete' => [ 'delete' ],
+               'delete_redir' => [ 'delete_redir' ],
                'restore' => [ 'restore' ],
                'event' => [ 'event' ],
                'revision' => [ 'revision' ],
@@@ -8386,9 -8382,9 +8388,9 @@@ $wgSearchRunSuggestedQuery = true
  /**
   * Where popular password file is located.
   *
 - * Default in core contains 50,000 most popular. This config
 + * Default in core contains 10,000 most popular. This config
   * allows you to change which file, in case you want to generate
 - * a password file with > 50000 entries in it.
 + * a password file with > 10000 entries in it.
   *
   * @see maintenance/createCommonPasswordCdb.php
   * @since 1.27
@@@ -938,8 -938,8 +938,8 @@@ class WikiPage implements Page, IDBAcce
                $dbw->startAtomic( __METHOD__ );
  
                if ( !$oldLatest || $oldLatest == $this->lockAndGetLatest() ) {
 -                      $dbw->replace( 'redirect',
 -                              [ 'rd_from' ],
 +                      $dbw->upsert(
 +                              'redirect',
                                [
                                        'rd_from' => $this->getId(),
                                        'rd_namespace' => $rt->getNamespace(),
                                        'rd_fragment' => $rt->getFragment(),
                                        'rd_interwiki' => $rt->getInterwiki(),
                                ],
 +                              [ 'rd_from' ],
 +                              [
 +                                      'rd_namespace' => $rt->getNamespace(),
 +                                      'rd_title' => $rt->getDBkey(),
 +                                      'rd_fragment' => $rt->getFragment(),
 +                                      'rd_interwiki' => $rt->getInterwiki(),
 +                              ],
                                __METHOD__
                        );
                }
                }
  
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
 -                      // @todo move this logic to MessageCache
 -                      if ( $this->exists() ) {
 -                              // NOTE: use transclusion text for messages.
 -                              //       This is consistent with  MessageCache::getMsgFromNamespace()
 -
 -                              $content = $this->getContent();
 -                              $text = $content === null ? null : $content->getWikitextForTransclusion();
 -
 -                              if ( $text === null ) {
 -                                      $text = false;
 -                              }
 -                      } else {
 -                              $text = false;
 -                      }
 -
 -                      MessageCache::singleton()->replace( $this->mTitle->getDBkey(), $text );
 +                      $messageCache = MessageCache::singleton();
 +                      $messageCache->updateMessageOverride( $this->mTitle, $this->getContent() );
                }
  
                return true;
         *   - 'no-change': don't update the article count, ever
         */
        public function doEditUpdates( Revision $revision, User $user, array $options = [] ) {
 -              global $wgRCWatchCategoryMembership, $wgContLang;
 +              global $wgRCWatchCategoryMembership;
  
                $options += [
                        'changed' => true,
                }
  
                if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
 -                      // XXX: could skip pseudo-messages like js/css here, based on content model.
 -                      $msgtext = $content ? $content->getWikitextForTransclusion() : null;
 -                      if ( $msgtext === false || $msgtext === null ) {
 -                              $msgtext = '';
 -                      }
 -
 -                      MessageCache::singleton()->replace( $shortTitle, $msgtext );
 -
 -                      if ( $wgContLang->hasVariants() ) {
 -                              $wgContLang->updateConversionTable( $this->mTitle );
 -                      }
 +                      MessageCache::singleton()->updateMessageOverride( $this->mTitle, $content );
                }
  
                if ( $options['created'] ) {
         */
        public function doDeleteArticleReal(
                $reason, $suppress = false, $u1 = null, $u2 = null, &$error = '', User $user = null,
-               $tags = []
+               $tags = [], $logsubtype = 'delete'
        ) {
                global $wgUser, $wgContentHandlerUseDB;
  
                // Log the deletion, if the page was suppressed, put it in the suppression log instead
                $logtype = $suppress ? 'suppress' : 'delete';
  
-               $logEntry = new ManualLogEntry( $logtype, 'delete' );
+               $logEntry = new ManualLogEntry( $logtype, $logsubtype );
                $logEntry->setPerformer( $user );
                $logEntry->setTarget( $logTitle );
                $logEntry->setComment( $reason );
         * @param Title $title
         */
        public static function onArticleDelete( Title $title ) {
 -              global $wgContLang;
 -
                // Update existence markers on article/talk tabs...
                $other = $title->getOtherPage();
  
  
                // Messages
                if ( $title->getNamespace() == NS_MEDIAWIKI ) {
 -                      MessageCache::singleton()->replace( $title->getDBkey(), false );
 -
 -                      if ( $wgContLang->hasVariants() ) {
 -                              $wgContLang->updateConversionTable( $title );
 -                      }
 +                      MessageCache::singleton()->updateMessageOverride( $title, null );
                }
  
                // Images
diff --combined languages/i18n/en.json
        "passwordreset-emaildisabled": "Email features have been disabled on this wiki.",
        "passwordreset-username": "Username:",
        "passwordreset-domain": "Domain:",
 -      "passwordreset-capture": "View the resulting email?",
 -      "passwordreset-capture-help": "If you check this box, the email (with the temporary password) will be shown to you as well as being sent to the user.",
        "passwordreset-email": "Email address:",
        "passwordreset-emailtitle": "Account details on {{SITENAME}}",
        "passwordreset-emailtext-ip": "Someone (probably you, from IP address $1) requested a reset of your\npassword for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}\nassociated with this email address:\n\n$2\n\n{{PLURAL:$3|This temporary password|These temporary passwords}} will expire in {{PLURAL:$5|one day|$5 days}}.\nYou should log in and choose a new password now. If someone else made this\nrequest, or if you have remembered your original password, and you no longer\nwish to change it, you may ignore this message and continue using your old\npassword.",
        "passwordreset-emailelement": "Username:\n$1\n\nTemporary password:\n$2",
        "passwordreset-emailsentemail": "If this email address is associated with your account, then a password reset email will be sent.",
        "passwordreset-emailsentusername": "If there is an email address associated with this username, then a password reset email will be sent.",
 -      "passwordreset-emailsent-capture2": "The password reset {{PLURAL:$1|email has|emails have}} been sent. The {{PLURAL:$1|username and password|list of usernames and passwords}} is shown here.",
 -      "passwordreset-emailerror-capture2": "Emailing the {{GENDER:$2|user}} failed: $1 The {{PLURAL:$3|username and password|list of usernames and passwords}} is shown here.",
        "passwordreset-nocaller": "A caller must be provided",
        "passwordreset-nosuchcaller": "Caller does not exist: $1",
        "passwordreset-ignored": "The password reset was not handled. Maybe no provider was configured?",
 -      "passwordreset-invalideamil": "Invalid email address",
 +      "passwordreset-invalidemail": "Invalid email address",
        "passwordreset-nodata": "Neither a username nor an email address was supplied",
        "changeemail": "Change or remove email address",
        "changeemail-summary": "",
        "right-siteadmin": "Lock and unlock the database",
        "right-override-export-depth": "Export pages including linked pages up to a depth of 5",
        "right-sendemail": "Send email to other users",
 -      "right-passwordreset": "View password reset emails",
        "right-managechangetags": "Create and (de)activate [[Special:Tags|tags]]",
        "right-applychangetags": "Apply [[Special:Tags|tags]] along with one's changes",
        "right-changetags": "Add and remove arbitrary [[Special:Tags|tags]] on individual revisions and log entries",
        "apisandbox-continue": "Continue",
        "apisandbox-continue-clear": "Clear",
        "apisandbox-continue-help": "{{int:apisandbox-continue}} will [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continue] the last request; {{int:apisandbox-continue-clear}} will clear continuation-related parameters.",
 +      "apisandbox-param-limit": "Enter <kbd>max</kbd> to use the maximum limit.",
 +      "apisandbox-multivalue-all-namespaces": "$1 (All namespaces)",
 +      "apisandbox-multivalue-all-values": "$1 (All values)",
        "booksources": "Book sources",
        "booksources-summary": "",
        "booksources-search-legend": "Search for book sources",
        "activeusers-count": "$1 {{PLURAL:$1|action|actions}} in the last {{PLURAL:$3|day|$3 days}}",
        "activeusers-from": "Display users starting at:",
        "activeusers-groups": "Display users belonging to groups:",
 +      "activeusers-excludegroups": "Exclude users belonging to groups:",
        "activeusers-noresult": "No users found.",
        "activeusers-submit": "Display active users",
        "listgrouprights": "User group rights",
        "tags-deactivate": "deactivate",
        "tags-hitcount": "$1 {{PLURAL:$1|change|changes}}",
        "tags-manage-no-permission": "You do not have permission to manage change tags.",
 -      "tags-manage-blocked": "You cannot manage change tags while you are blocked.",
 +      "tags-manage-blocked": "You cannot manage change tags while {{GENDER:$1|you}} are blocked.",
        "tags-create-heading": "Create a new tag",
        "tags-create-explanation": "By default, newly created tags will be made available for use by users and bots.",
        "tags-create-tag-name": "Tag name:",
        "tags-deactivate-not-allowed": "It is not possible to deactivate the tag \"$1\".",
        "tags-deactivate-submit": "Deactivate",
        "tags-apply-no-permission": "You do not have permission to apply change tags along with your changes.",
 -      "tags-apply-blocked": "You cannot apply change tags along with your changes while you are blocked.",
 +      "tags-apply-blocked": "You cannot apply change tags along with your changes while {{GENDER:$1|you}} are blocked.",
        "tags-apply-not-allowed-one": "The tag \"$1\" is not allowed to be manually applied.",
        "tags-apply-not-allowed-multi": "The following {{PLURAL:$2|tag is|tags are}} not allowed to be manually applied: $1",
        "tags-update-no-permission": "You do not have permission to add or remove change tags from individual revisions or log entries.",
 -      "tags-update-blocked": "You cannot add or remove change tags while you are blocked.",
 +      "tags-update-blocked": "You cannot add or remove change tags while {{GENDER:$1|you}} are blocked.",
        "tags-update-add-not-allowed-one": "The tag \"$1\" is not allowed to be manually added.",
        "tags-update-add-not-allowed-multi": "The following {{PLURAL:$2|tag is|tags are}} not allowed to be manually added: $1",
        "tags-update-remove-not-allowed-one": "The tag \"$1\" is not allowed to be removed.",
        "htmlform-user-not-valid": "<strong>$1</strong> isn't a valid username.",
        "rawmessage": "$1",
        "logentry-delete-delete": "$1 {{GENDER:$2|deleted}} page $3",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|deleted}} redirect $3 by overwriting",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
        "logentry-delete-event": "$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4",
        "mw-widgets-dateinput-placeholder-month": "YYYY-MM",
        "mw-widgets-titleinput-description-new-page": "page does not exist yet",
        "mw-widgets-titleinput-description-redirect": "redirect to $1",
 +      "mw-widgets-categoryselector-add-category-placeholder": "Add a category...",
        "sessionmanager-tie": "Cannot combine multiple request authentication types: $1.",
        "sessionprovider-generic": "$1 sessions",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-based sessions",
        "log-action-filter-contentmodel-change": "Change of Contentmodel",
        "log-action-filter-contentmodel-new": "Creation of page with non-standard Contentmodel",
        "log-action-filter-delete-delete": "Page deletion",
+       "log-action-filter-delete-delete_redir": "Redirect overwrite",
        "log-action-filter-delete-restore": "Page undeletion",
        "log-action-filter-delete-event": "Log deletion",
        "log-action-filter-delete-revision": "Revision deletion",
diff --combined languages/i18n/qqq.json
        "passwordreset-emaildisabled": "Used as error message in changing password when site's email feature is disabled.",
        "passwordreset-username": "{{Identical|Username}}",
        "passwordreset-domain": "A domain like used in Domain Name System (DNS) or more specifically like a domain component in the Lightweight Directory Access Protocol (LDAP).\n{{Identical|Domain}}",
 -      "passwordreset-capture": "Label for checkbox asking the user whether they want to see the contents of the password reset email (only shown if they have the <code>passwordreset</code> permission).",
 -      "passwordreset-capture-help": "Longer explanatory message for the capture checkbox label.",
        "passwordreset-email": "{{Identical|E-mail address}}",
        "passwordreset-emailtitle": "Used as subject (title) of email.",
        "passwordreset-emailtext-ip": "Be consistent with {{msg-mw|Passwordreset-emailtext-user}}.\n\nParameters:\n* $1 - an IP address\n* $2 - message {{msg-mw|Passwordreset-emailelement}} repeated $3 times\n* $3 - the number of repetitions in $2\n* $4 - base URL of the wiki\n* $5 - number of days",
        "passwordreset-emailelement": "This is a body of a password reset email to allow them into the system with a new password. Parameters:\n* $1 - the user's login name. This parameter can be used for GENDER.\n* $2 - the temporary password given by the system",
        "passwordreset-emailsentemail": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
        "passwordreset-emailsentusername": "Used in [[Special:PasswordReset]].\n\nSee also:\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
 -      "passwordreset-emailsent-capture2": "Used in [[Special:PasswordReset]].\n\nParameters:\n* $1 - number of accounts notified\n\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {{msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
 -      "passwordreset-emailerror-capture2": "Error message displayed in [[Special:PasswordReset]] when sending an email fails. Parameters:\n* $1 - error message\n* $2 - username, used for GENDER\n* $3 - number of accounts notified\n\nSee also:\n* {{msg-mw|Passwordreset-emailsentemail}}\n* {{msg-mw|Passwordreset-emailsentusername}}\n* {{msg-mw|Passwordreset-emailsent-capture}}\n* {{msg-mw|Passwordreset-emailerror-capture}}",
        "passwordreset-nocaller": "Shown when a password reset was requested but the process failed due to an internal error related to missing details about the origin (caller) of the password reset request.",
        "passwordreset-nosuchcaller": "Shown when a password reset was requested but the username of the caller could not be resolved to a user. This is an internal error.\n\nParameters:\n* $1 - username of the caller",
        "passwordreset-ignored": "Shown when password reset was unsuccessful due to configuration problems.",
 -      "passwordreset-invalideamil": "Returned when the email address is syntatically invalid.",
 +      "passwordreset-invalidemail": "Returned when the email address is syntatically invalid.",
        "passwordreset-nodata": "Returned when no data was provided.",
        "changeemail": "Title of [[Special:ChangeEmail|special page]]. This page also allows removing the user's email address.",
        "changeemail-summary": "{{ignored}}",
        "right-siteadmin": "{{doc-right|siteadmin}}",
        "right-override-export-depth": "{{doc-right|override-export-depth}}",
        "right-sendemail": "{{doc-right|sendemail}}",
 -      "right-passwordreset": "{{doc-right|passwordreset}}",
        "right-managechangetags": "{{doc-right|managechangetags}}",
        "right-applychangetags": "{{doc-right|applychangetags}}",
        "right-changetags": "{{doc-right|changetags}}",
        "grant-patrol": "Name for grant \"patrol\".\n{{Related|Grant}}",
        "grant-privateinfo": "Name for grant \"privateinfo\".\n{{Related|Grant}}",
        "grant-protect": "Name for grant \"protect\".\n{{Related|Grant}}",
 -      "grant-rollback": "Name for grant \"rollback\".\n{{Related|Grant}}",
 +      "grant-rollback": "Name for grant \"rollback\".\n{{Related|Grant}}\n{{Identical|Rollback}}",
        "grant-sendemail": "Name for grant \"sendemail\".\n{{Related|Grant}}",
        "grant-uploadeditmovefile": "Name for grant \"uploadeditmovefile\".\n{{Related|Grant}}",
        "grant-uploadfile": "Name for grant \"uploadfile\".\n{{Related|Grant}}\n{{Identical|Upload new file}}",
        "action-suppressionlog": "{{Doc-action|suppressionlog}}",
        "action-block": "{{Doc-action|block}}",
        "action-protect": "{{Doc-action|protect}}",
 -      "action-rollback": "{{Doc-action|rollback}}",
 +      "action-rollback": "{{Doc-action|rollback}}\n{{Identical|Rollback}}",
        "action-import": "{{Doc-action|import}}",
        "action-importupload": "{{Doc-action|importupload}}",
        "action-patrol": "{{Doc-action|patrol}}",
        "apisandbox-continue": "Button text for sending another request using query continuation.\n{{Identical|Continue}}",
        "apisandbox-continue-clear": "Button text for clearing query continuation parameters.\n{{Identical|Clear}}",
        "apisandbox-continue-help": "Help text for the continue and clear buttons.",
 +      "apisandbox-param-limit": "Additional documentation text for 'limit'-type parameters.",
 +      "apisandbox-multivalue-all-namespaces": "Used as an entry in a multiple-namespace widget to select all available namespaces. Parameters:\n* $1 - API input value meaning \"all namespaces\".",
 +      "apisandbox-multivalue-all-values": "Used as an entry in a multiple-value widget to select all available values. Parameters:\n* $1 - API input value meaning \"all values\".",
        "booksources": "{{doc-special|BookSources}}\n\n'''This message shouldn't be changed unless it has serious mistakes.'''\n\nIt's used as the page name of the configuration page of [[Special:BookSources]]. Changing it breaks existing sites using the default version of this message.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-summary": "{{doc-specialpagesummary|booksources}}",
        "booksources-search-legend": "Box heading on [[Special:BookSources|book sources]] special page. The box is for searching for places where a particular book can be bought or viewed.",
        "activeusers-count": "Used in [[Special:ActiveUsers]] to show the active user's recent action count in brackets ([]).\n* $1 is the number of recent actions\n* $2 is the user's name for use with GENDER (optional)\n* $3 is the maximum number of days of the RecentChangesList",
        "activeusers-from": "Used as label for checkbox in the form on [[Special:ActiveUsers]].\n\nidentical with {{msg-mw|listusersfrom}}\n\nSee also:\n* {{msg-mw|activeusers|legend for the form}}",
        "activeusers-groups": "Used as label on [[Special:ActiveUsers]].",
 +      "activeusers-excludegroups": "Used as an option on [[Special:ActiveUsers]].",
        "activeusers-noresult": "identical with {{msg-mw|listusers-noresult}}",
        "activeusers-submit": "Used as label for button in the form on [[Special:ActiveUsers]]",
        "listgrouprights": "The name of the special page [[Special:ListGroupRights]].",
        "tags-deactivate": "Used on [[Special:Tags]]. Verb. Used as display text on a link to deactivate a tag.\n{{Identical|Delete}}",
        "tags-hitcount": "Shown in the \"{{msg-mw|Tags-hitcount-header}}\" column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n\nParameters:\n* $1 - the number of changes marked with the tag",
        "tags-manage-no-permission": "Error message on [[Special:Tags]]",
 -      "tags-manage-blocked": "Error message on [[Special:Tags]]",
 +      "tags-manage-blocked": "Error message on [[Special:Tags]]\n\nParameters:\n* $1 - user name for gender",
        "tags-create-heading": "The title of a fieldset, beneath which lies a form used to create a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
        "tags-create-explanation": "The first paragraph of an explanation to tell users what they are about to do.",
        "tags-create-tag-name": "Form field label for the name of the tag to be created.",
        "tags-deactivate-not-allowed": "Error message on [[Special:Tags]]",
        "tags-deactivate-submit": "The label of the form \"submit\" button when the user is about to deactivate a tag.\n{{Identical|Deactivate}}",
        "tags-apply-no-permission": "Error message seen via the API when a user lacks the permission to apply change tags.",
 -      "tags-apply-blocked": "Error message seen via the API when a user is blocked and attempted to apply change tags.",
 +      "tags-apply-blocked": "Error message seen via the API when a user is blocked and attempted to apply change tags.\n\nParameters:\n* $1 - user name for gender",
        "tags-apply-not-allowed-one": "Error message seen via the API when a user tries to apply a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "tags-apply-not-allowed-multi": "Error message seen via the API when a user tries to apply more than one tag that is not properly defined.\n\nParameters:\n* $1 - comma-separated list of tag names\n* $2 - number of tags",
        "tags-update-no-permission": "Error message seen via the API when a user lacks the permission to add or remove change tags after the fact.",
 -      "tags-update-blocked": "Error message seen via the API when a user is blocked and attempted to add or remove change tags after the fact.",
 +      "tags-update-blocked": "Error message seen via the API when a user is blocked and attempted to add or remove change tags after the fact.\n\nParameters:\n* $1 - user name for gender",
        "tags-update-add-not-allowed-one": "Error message seen via the API when a user tries to add a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "tags-update-add-not-allowed-multi": "Error message seen via the API when a user tries to add more than one tag that is not properly defined.\n\nParameters:\n* $1 - comma-separated list of tag names\n* $2 - number of tags",
        "tags-update-remove-not-allowed-one": "Error message seen via the API when a user tries to remove a single tag that is not properly defined. This message is only ever used in the case of 1 tag.\n\nParameters:\n* $1 - tag name",
        "htmlform-user-not-valid": "Error message shown if the name provided by the user isn't a valid username. $1 is the username.",
        "rawmessage": "{{notranslate}} Used to pass arbitrary text as a message specifier array",
        "logentry-delete-delete": "{{Logentry|[[Special:Log/delete]]}}",
+       "logentry-delete-delete_redir": "{{Logentry|[[Special:Log/delete]]}}",
        "logentry-delete-restore": "{{Logentry|[[Special:Log/delete]]}}",
        "logentry-delete-event": "{{Logentry|[[Special:Log/delete]]}}\n{{Logentryparam}}\n* $5 - count of affected log events",
        "logentry-delete-revision": "{{Logentry|[[Special:Log/delete]]}}\n{{Logentryparam}}\n* $5 - the number of affected revisions of the page $3",
        "mediastatistics-header-audio": "Header on [[Special:MediaStatistics]] for file types that are in the audio category\n{{Identical|Audio}}",
        "mediastatistics-header-video": "Header on [[Special:MediaStatistics]] for file types that are in the video category\n{{Identical|Video}}",
        "mediastatistics-header-multimedia": "Header on [[Special:MediaStatistics]] for file types that are in the multimedia category. This does not include plain audio or video files, but more complex multimedia such as flash or vrml. This especially includes scripted multimedia. Ogg files in which MediaWiki cannot determine if it is an audio or video file (or something else) are included here.",
 -      "mediastatistics-header-office": "Header on [[Special:MediaStatistics]] for file types that are in the Office category. This includes PDFs, OpenDocument files, Microsoft Word files, etc.",
 +      "mediastatistics-header-office": "Header on [[Special:MediaStatistics]] for file types that are in the Office category. This includes PDFs, OpenDocument files, Microsoft Word files, etc.\n{{Identical|Office}}",
        "mediastatistics-header-text": "Header on [[Special:MediaStatistics]] for file types that are in the text category. This includes simple text formats, including plain text formats, json, csv, and xml. Source code of compiled programming languages may be included here in the future, but isn't currently.",
        "mediastatistics-header-executable": "Header on [[Special:MediaStatistics]] for file types that are in the executable category. This includes things like source files for interpreted programming language (Shell scripts, javascript, etc).",
        "mediastatistics-header-archive": "Header on [[Special:MediaStatistics]] for file types that are in the archive category. Includes things like tar, zip, gzip etc.",
        "mw-widgets-dateinput-placeholder-month": "Placeholder displayed in a date input field when it's empty, representing a date format with 4 digits for year and 2 digits for month, separated with hyphens (without a day). This should be uppercase, if possible, and must not include any additional explanations. If there is no good way to translate it, make this message blank.",
        "mw-widgets-titleinput-description-new-page": "Description label for a new page in the title input widget.",
        "mw-widgets-titleinput-description-redirect": "Description label for a redirect in the title input widget.",
 +      "mw-widgets-categoryselector-add-category-placeholder": "Placeholder displayed in the category selector widget after the capsules of already added categories.",
        "sessionmanager-tie": "Used as an error message when multiple session sources are tied in priority.\n\nParameters:\n* $1 - List of dession type descriptions, from messages like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.",
        "sessionprovider-generic": "Used to create a generic session type description when one isn't provided via the proper message. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.\n\nParameters:\n* $1 - PHP classname.",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "Description of the sessions provided by the CookieSessionProvider class, which use HTTP cookies. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.",
        "log-action-filter-contentmodel-change": "{{doc-log-action-filter-action|contentmodel|change}}",
        "log-action-filter-contentmodel-new": "{{doc-log-action-filter-action|contentmodel|new}}",
        "log-action-filter-delete-delete": "{{doc-log-action-filter-action|delete|delete}}",
+       "log-action-filter-delete-delete_redir": "{{doc-log-action-filter-action|delete|delete_redir}}",
        "log-action-filter-delete-restore": "{{doc-log-action-filter-action|delete|restore}}",
        "log-action-filter-delete-event": "{{doc-log-action-filter-action|delete|event}}",
        "log-action-filter-delete-revision": "{{doc-log-action-filter-action|delete|revision}}",