Merge "Split editcascadeprotected permission from protect permission"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 12 May 2016 20:37:00 +0000 (20:37 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 12 May 2016 20:37:00 +0000 (20:37 +0000)
1  2 
includes/DefaultSettings.php
includes/Title.php
includes/user/User.php
languages/i18n/en.json
languages/i18n/qqq.json

@@@ -75,7 -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
@@@ -4492,9 -4492,9 +4492,9 @@@ $wgPasswordConfig = 
        ],
        'pbkdf2' => [
                'class' => 'Pbkdf2Password',
 -              'algo' => 'sha256',
 -              'cost' => '10000',
 -              'length' => '128',
 +              'algo' => 'sha512',
 +              'cost' => '30000',
 +              'length' => '64',
        ],
  ];
  
@@@ -4882,6 -4882,7 +4882,7 @@@ $wgGroupPermissions['sysop']['move-cate
  $wgGroupPermissions['sysop']['patrol'] = true;
  $wgGroupPermissions['sysop']['autopatrol'] = true;
  $wgGroupPermissions['sysop']['protect'] = true;
+ $wgGroupPermissions['sysop']['editcascadeprotected'] = true;
  $wgGroupPermissions['sysop']['editprotected'] = true;
  $wgGroupPermissions['sysop']['rollback'] = true;
  $wgGroupPermissions['sysop']['upload'] = true;
@@@ -5478,6 -5479,7 +5479,7 @@@ $wgGrantPermissions['delete']['undelete
  
  $wgGrantPermissions['protect'] = $wgGrantPermissions['editprotected'];
  $wgGrantPermissions['protect']['protect'] = true;
+ $wgGrantPermissions['protect']['editcascadeprotected'] = true;
  
  $wgGrantPermissions['viewmywatchlist']['viewmywatchlist'] = true;
  
@@@ -7291,7 -7293,7 +7293,7 @@@ $wgActionFilteredLogs = 
        ],
        'newusers' => [
                'create' => [ 'create', 'newusers' ],
 -              'create2' => ['create2' ],
 +              'create2' => [ 'create2' ],
                'autocreate' => [ 'autocreate' ],
                'byemail' => [ 'byemail' ],
        ],
                'protect' => [ 'protect' ],
                'modify' => [ 'modify' ],
                'unprotect' => [ 'unprotect' ],
 -              'move_prot' => ['move_prot'],
 +              'move_prot' => [ 'move_prot' ],
        ],
        'rights' => [
                'rights' => [ 'rights' ],
@@@ -7990,23 -7992,6 +7992,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).
diff --combined includes/Title.php
@@@ -22,7 -22,6 +22,7 @@@
   * @file
   */
  use MediaWiki\Linker\LinkTarget;
 +use MediaWiki\MediaWikiServices;
  
  /**
   * Represents a title within MediaWiki.
@@@ -158,6 -157,42 +158,6 @@@ class Title implements LinkTarget 
        private $mIsBigDeletion = null;
        // @}
  
 -      /**
 -       * B/C kludge: provide a TitleParser for use by Title.
 -       * Ideally, Title would have no methods that need this.
 -       * Avoid usage of this singleton by using TitleValue
 -       * and the associated services when possible.
 -       *
 -       * @return MediaWikiTitleCodec
 -       */
 -      private static function getMediaWikiTitleCodec() {
 -              global $wgContLang, $wgLocalInterwikis;
 -
 -              static $titleCodec = null;
 -              static $titleCodecFingerprint = null;
 -
 -              // $wgContLang and $wgLocalInterwikis may change (especially while testing),
 -              // make sure we are using the right one. To detect changes over the course
 -              // of a request, we remember a fingerprint of the config used to create the
 -              // codec singleton, and re-create it if the fingerprint doesn't match.
 -              $fingerprint = spl_object_hash( $wgContLang ) . '|' . implode( '+', $wgLocalInterwikis );
 -
 -              if ( $fingerprint !== $titleCodecFingerprint ) {
 -                      $titleCodec = null;
 -              }
 -
 -              if ( !$titleCodec ) {
 -                      $titleCodec = new MediaWikiTitleCodec(
 -                              $wgContLang,
 -                              GenderCache::singleton(),
 -                              $wgLocalInterwikis
 -                      );
 -                      $titleCodecFingerprint = $fingerprint;
 -              }
 -
 -              return $titleCodec;
 -      }
 -
        /**
         * B/C kludge: provide a TitleParser for use by Title.
         * Ideally, Title would have no methods that need this.
         * @return TitleFormatter
         */
        private static function getTitleFormatter() {
 -              // NOTE: we know that getMediaWikiTitleCodec() returns a MediaWikiTitleCodec,
 -              //      which implements TitleFormatter.
 -              return self::getMediaWikiTitleCodec();
 +              return MediaWikiServices::getInstance()->getTitleFormatter();
        }
  
 +      /**
 +       * @access protected
 +       */
        function __construct() {
        }
  
                        }
                        if ( !$user->isAllowed( $right ) ) {
                                $errors[] = [ 'protectedpagetext', $right, $action ];
-                       } elseif ( $this->mCascadeRestriction && !$user->isAllowed( 'protect' ) ) {
+                       } elseif ( $this->mCascadeRestriction &&
+                               !$user->isAllowedAny( 'editcascadeprotected', 'protect' ) )
+                       {
                                $errors[] = [ 'protectedpagetext', 'protect', $action ];
                        }
                }
                                        if ( $right == 'autoconfirmed' ) {
                                                $right = 'editsemiprotected';
                                        }
-                                       if ( $right != '' && !$user->isAllowedAll( 'protect', $right ) ) {
+                                       if ( $right != '' && !$user->isAllowed( $right ) &&
+                                               !$user->isAllowedAny( 'editcascadeprotected', 'protect' ) )
+                                       {
                                                $pages = '';
                                                foreach ( $cascadingSources as $page ) {
                                                        $pages .= '* [[:' . $page->getPrefixedText() . "]]\n";
                // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share
                //        the parsing code with Title, while avoiding massive refactoring.
                // @todo: get rid of secureAndSplit, refactor parsing code.
 -              $titleParser = self::getMediaWikiTitleCodec();
 +              // @note: getTitleParser() returns a TitleParser implementation which does not have a
 +              //        splitTitleString method, but the only implementation (MediaWikiTitleCodec) does
 +              $titleCodec = MediaWikiServices::getInstance()->getTitleParser();
                // MalformedTitleException can be thrown here
 -              $parts = $titleParser->splitTitleString( $dbkey, $this->getDefaultNamespace() );
 +              $parts = $titleCodec->splitTitleString( $dbkey, $this->getDefaultNamespace() );
  
                # Fill fields
                $this->setFragment( '#' . $parts['fragment'] );
                        $this->mNotificationTimestamp = [];
                }
  
 -              $watchedItem = WatchedItemStore::getDefaultInstance()->getWatchedItem( $user, $this );
 +              $store = MediaWikiServices::getInstance()->getWatchedItemStore();
 +              $watchedItem = $store->getWatchedItem( $user, $this );
                if ( $watchedItem ) {
                        $this->mNotificationTimestamp[$uid] = $watchedItem->getNotificationTimestamp();
                } else {
diff --combined includes/user/User.php
@@@ -132,6 -132,7 +132,7 @@@ class User implements IDBAccessObject 
                'deletelogentry',
                'deleterevision',
                'edit',
+               'editcascadeprotected',
                'editcontentmodel',
                'editinterface',
                'editprotected',
         */
        protected static function getInProcessCache() {
                if ( !self::$inProcessCache ) {
 -                      self::$inProcessCache = new HashBagOStuff( ['maxKeys' => 10] );
 +                      self::$inProcessCache = new HashBagOStuff( [ 'maxKeys' => 10 ] );
                }
                return self::$inProcessCache;
        }
                        throw new PasswordError( wfMessage( 'externaldberror' )->text() );
                }
  
 -              $this->setToken();
                $this->setOption( 'watchlisttoken', false );
                $this->setPasswordInternal( $str );
 +              SessionManager::singleton()->invalidateSessionsForUser( $this );
  
                return true;
        }
                global $wgAuth;
  
                if ( $wgAuth->allowSetLocalPassword() ) {
 -                      $this->setToken();
                        $this->setOption( 'watchlisttoken', false );
                        $this->setPasswordInternal( $str );
 +                      SessionManager::singleton()->invalidateSessionsForUser( $this );
                }
        }
  
                return !$this->isLoggedIn();
        }
  
 +      /**
 +       * @return bool Whether this user is flagged as being a bot role account
 +       * @since 1.28
 +       */
 +      public function isBot() {
 +              $isBot = false;
 +              if ( !Hooks::run( "UserIsBot", [ $this, &$isBot ] ) ) {
 +                      return $isBot;
 +              }
 +
 +              return ( $isBot || in_array( 'bot', $this->getGroups() ) );
 +      }
 +
        /**
         * Check if user is allowed to access a feature / make an action
         *
         */
        public function isWatched( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( $title->isWatchable() && ( !$checkRights || $this->isAllowed( 'viewmywatchlist' ) ) ) {
 -                      return WatchedItemStore::getDefaultInstance()->isWatched( $this, $title );
 +                      return MediaWikiServices::getInstance()->getWatchedItemStore()->isWatched( $this, $title );
                }
                return false;
        }
         */
        public function addWatch( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( !$checkRights || $this->isAllowed( 'editmywatchlist' ) ) {
 -                      WatchedItemStore::getDefaultInstance()->addWatchBatchForUser(
 +                      MediaWikiServices::getInstance()->getWatchedItemStore()->addWatchBatchForUser(
                                $this,
                                [ $title->getSubjectPage(), $title->getTalkPage() ]
                        );
         */
        public function removeWatch( $title, $checkRights = self::CHECK_USER_RIGHTS ) {
                if ( !$checkRights || $this->isAllowed( 'editmywatchlist' ) ) {
 -                      WatchedItemStore::getDefaultInstance()->removeWatch( $this, $title->getSubjectPage() );
 -                      WatchedItemStore::getDefaultInstance()->removeWatch( $this, $title->getTalkPage() );
 +                      $store = MediaWikiServices::getInstance()->getWatchedItemStore();
 +                      $store->removeWatch( $this, $title->getSubjectPage() );
 +                      $store->removeWatch( $this, $title->getTalkPage() );
                }
                $this->invalidateCache();
        }
                        $force = 'force';
                }
  
 -              WatchedItemStore::getDefaultInstance()
 +              MediaWikiServices::getInstance()->getWatchedItemStore()
                        ->resetNotificationTimestamp( $this, $title, $force, $oldid );
        }
  
diff --combined languages/i18n/en.json
@@@ -43,7 -43,7 +43,7 @@@
        "tog-ccmeonemails": "Send me copies of emails I send to other users",
        "tog-diffonly": "Do not show page content below diffs",
        "tog-showhiddencats": "Show hidden categories",
 -      "tog-norollbackdiff": "Omit diff after performing a rollback",
 +      "tog-norollbackdiff": "Don't show diff after performing a rollback",
        "tog-useeditwarning": "Warn me when I leave an edit page with unsaved changes",
        "tog-prefershttps": "Always use a secure connection when logged in",
        "underline-always": "Always",
        "right-hideuser": "Block a username, hiding it from the public",
        "right-ipblock-exempt": "Bypass IP blocks, auto-blocks and range blocks",
        "right-unblockself": "Unblock oneself",
-       "right-protect": "Change protection levels and edit cascade-protected pages",
+       "right-protect": "Change protection levels",
+       "right-editcascadeprotected": "Edit cascade-protected pages",
        "right-editprotected": "Edit pages protected as \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "Edit pages protected as \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Edit the content model of a page",
        "upload-form-label-infoform-description-tooltip": "Briefly describe everything notable about the work.\nFor a photo, mention the main things that are depicted, the occasion, or the place.",
        "upload-form-label-usage-title": "Usage",
        "upload-form-label-usage-filename": "File name",
 -      "foreign-structured-upload-form-label-own-work": "This is my own work",
 -      "foreign-structured-upload-form-label-infoform-categories": "Categories",
 -      "foreign-structured-upload-form-label-infoform-date": "Date",
 -      "foreign-structured-upload-form-label-own-work-message-local": "I confirm that I am uploading this file following the terms of service and licensing policies on {{SITENAME}}.",
 -      "foreign-structured-upload-form-label-not-own-work-message-local": "If you are not able to upload this file under the policies of {{SITENAME}}, please close this dialog and try another method.",
 -      "foreign-structured-upload-form-label-not-own-work-local-local": "You may also want to try [[Special:Upload|the default upload page]].",
 -      "foreign-structured-upload-form-label-own-work-message-default": "I understand that I am uploading this file to a shared repository. I confirm that I am doing so following the terms of service and licensing policies there.",
 -      "foreign-structured-upload-form-label-not-own-work-message-default": "If you are not able to upload this file under the policies of the shared repository, please close this dialog and try another method.",
 -      "foreign-structured-upload-form-label-not-own-work-local-default": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if this file can be uploaded there under their policies.",
 -      "foreign-structured-upload-form-label-own-work-message-shared": "I attest that I own the copyright on this file, and agree to irrevocably release this file to Wikimedia Commons under the [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] license, and I agree to the [https://wikimediafoundation.org/wiki/Terms_of_Use Terms of Use].",
 -      "foreign-structured-upload-form-label-not-own-work-message-shared": "If you do not own the copyright on this file, or you wish to release it under a different license, consider using the [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
 -      "foreign-structured-upload-form-label-not-own-work-local-shared": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if the site allows the upload of this file under their policies.",
 +      "upload-form-label-own-work": "This is my own work",
 +      "upload-form-label-infoform-categories": "Categories",
 +      "upload-form-label-infoform-date": "Date",
 +      "upload-form-label-own-work-message-local": "I confirm that I am uploading this file following the terms of service and licensing policies on {{SITENAME}}.",
 +      "upload-form-label-not-own-work-message-local": "If you are not able to upload this file under the policies of {{SITENAME}}, please close this dialog and try another method.",
 +      "upload-form-label-not-own-work-local-local": "You may also want to try [[Special:Upload|the default upload page]].",
 +      "upload-form-label-own-work-message-default": "I understand that I am uploading this file to a shared repository. I confirm that I am doing so following the terms of service and licensing policies there.",
 +      "upload-form-label-not-own-work-message-default": "If you are not able to upload this file under the policies of the shared repository, please close this dialog and try another method.",
 +      "upload-form-label-not-own-work-local-default": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if this file can be uploaded there under their policies.",
 +      "upload-form-label-own-work-message-shared": "I attest that I own the copyright on this file, and agree to irrevocably release this file to Wikimedia Commons under the [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0] license, and I agree to the [https://wikimediafoundation.org/wiki/Terms_of_Use Terms of Use].",
 +      "upload-form-label-not-own-work-message-shared": "If you do not own the copyright on this file, or you wish to release it under a different license, consider using the [https://commons.wikimedia.org/wiki/Special:UploadWizard Commons Upload Wizard].",
 +      "upload-form-label-not-own-work-local-shared": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if the site allows the upload of this file under their policies.",
        "backend-fail-stream": "Could not stream file \"$1\".",
        "backend-fail-backup": "Could not backup file \"$1\".",
        "backend-fail-notexists": "The file $1 does not exist.",
        "changecontentmodel-success-text": "The content type of [[:$1]] has been changed.",
        "changecontentmodel-cannot-convert": "The content on [[:$1]] cannot be converted to a type of $2.",
        "changecontentmodel-nodirectediting": "The $1 content model does not support direct editing",
 +      "changecontentmodel-emptymodels-title": "No content models available",
 +      "changecontentmodel-emptymodels-text": "The content on [[:$1]] cannot be converted to any type.",
        "log-name-contentmodel": "Content model change log",
        "log-description-contentmodel": "Events related to the content models of a page",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|created}} the page $3 using a non-default content model \"$5\"",
        "whatlinkshere-prev": "{{PLURAL:$1|previous|previous $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|next|next $1}}",
        "whatlinkshere-links": "← links",
 -      "whatlinkshere-hideredirs": "$1 redirects",
 -      "whatlinkshere-hidetrans": "$1 transclusions",
 -      "whatlinkshere-hidelinks": "$1 links",
 -      "whatlinkshere-hideimages": "$1 file links",
 +      "whatlinkshere-hideredirs": "Hide redirects",
 +      "whatlinkshere-hidetrans": "Hide transclusions",
 +      "whatlinkshere-hidelinks": "Hide links",
 +      "whatlinkshere-hideimages": "Hide file links",
        "whatlinkshere-filters": "Filters",
        "whatlinkshere-submit": "Go",
        "autoblockid": "Autoblock #$1",
        "lockdbsuccesstext": "The database has been locked.<br />\nRemember to [[Special:UnlockDB|remove the lock]] after your maintenance is complete.",
        "unlockdbsuccesstext": "The database has been unlocked.",
        "lockfilenotwritable": "The database lock file is not writable.\nTo lock or unlock the database, this needs to be writable by the web server.",
 +      "databaselocked": "The database is already locked.",
        "databasenotlocked": "The database is not locked.",
        "lockedbyandtime": "(by {{GENDER:$1|$1}} on $2 at $3)",
        "move-page": "Move $1",
diff --combined languages/i18n/qqq.json
        "right-ipblock-exempt": "{{doc-right|ipblock-exempt}}\nThis user automatically bypasses IP blocks, auto-blocks and range blocks - so I presume - but I am uncertain",
        "right-unblockself": "{{doc-right|unblockself}}",
        "right-protect": "{{doc-right|protect}}",
+       "right-editcascadeprotected": "{{doc-right|editcascadeprotected}}",
        "right-editprotected": "{{doc-right|editprotected}}\nRefers to {{msg-mw|Protect-level-sysop}}.\n\nSee also:\n* {{msg-mw|Right-editsemiprotected}}",
        "right-editsemiprotected": "{{doc-right|editsemiprotected}}\nRefers to {{msg-mw|Protect-level-autoconfirmed}}.\n\nSee also:\n* {{msg-mw|Right-editprotected}}",
        "right-editcontentmodel": "{{doc-right|editcontentmodel}}",
        "upload-form-label-infoform-description-tooltip": "The tooltip documenting the description fields on the details page.\n\nIdentical to {{msg-mw|mwe-upwiz-tooltip-description}}.",
        "upload-form-label-usage-title": "Title for the insert form showing how to use the uploaded item.\n{{Identical|Usage}}",
        "upload-form-label-usage-filename": "Label for the file name input\n{{Identical|Filename}}",
 -      "foreign-structured-upload-form-label-own-work": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Label for own work confirmation checkbox",
 -      "foreign-structured-upload-form-label-infoform-categories": "Label for category selector input\n{{Identical|Category}}",
 -      "foreign-structured-upload-form-label-infoform-date": "Label for date input\n{{Identical|Date}}",
 -      "foreign-structured-upload-form-label-own-work-message-local": "Message shown by local when a user affirms that their file upload to the local wiki follows the terms of service and licensing policies of the local wiki.",
 -      "foreign-structured-upload-form-label-not-own-work-message-local": "Message shown by local when a user cannot upload a file to the local wiki.",
 -      "foreign-structured-upload-form-label-not-own-work-local-local": "Suggests uploading a file via Special:Upload instead of using whatever method they're currently using.",
 -      "foreign-structured-upload-form-label-own-work-message-default": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
 -      "foreign-structured-upload-form-label-not-own-work-message-default": "Message shown by default when a user cannot upload a file to a remote wiki.",
 -      "foreign-structured-upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki.",
 -      "foreign-structured-upload-form-label-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Legal message, confirming that the user is allowed to upload the file.",
 -      "foreign-structured-upload-form-label-not-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Explains alternatives when the copyright isn't owned by the uploader.",
 -      "foreign-structured-upload-form-label-not-own-work-local-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Message suggesting the user might want to upload a file locally instead of to Wikimedia Commons.",
 +      "upload-form-label-own-work": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Label for own work confirmation checkbox",
 +      "upload-form-label-infoform-categories": "Label for category selector input\n{{Identical|Category}}",
 +      "upload-form-label-infoform-date": "Label for date input\n{{Identical|Date}}",
 +      "upload-form-label-own-work-message-local": "Message shown by local when a user affirms that their file upload to the local wiki follows the terms of service and licensing policies of the local wiki.",
 +      "upload-form-label-not-own-work-message-local": "Message shown by local when a user cannot upload a file to the local wiki.",
 +      "upload-form-label-not-own-work-local-local": "Suggests uploading a file via Special:Upload instead of using whatever method they're currently using.",
 +      "upload-form-label-own-work-message-default": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
 +      "upload-form-label-not-own-work-message-default": "Message shown by default when a user cannot upload a file to a remote wiki.",
 +      "upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki.",
 +      "upload-form-label-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Legal message, confirming that the user is allowed to upload the file.",
 +      "upload-form-label-not-own-work-message-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Explains alternatives when the copyright isn't owned by the uploader.",
 +      "upload-form-label-not-own-work-local-shared": "[[File:Cross-wiki media upload dialog, December 2015 AB test option 1.png|thumb]] Message suggesting the user might want to upload a file locally instead of to Wikimedia Commons.",
        "backend-fail-stream": "Parameters:\n* $1 - a filename",
        "backend-fail-backup": "Parameters:\n* $1 - a filename",
        "backend-fail-notexists": "Parameters:\n* $1 - a filename",
        "changecontentmodel-success-text": "Message telling user that their change has been successfully done.\n* $1 - Target page title",
        "changecontentmodel-cannot-convert": "Error message shown if the content model cannot be changed to the specified type. $1 is the page title, $2 is the localized content model name.",
        "changecontentmodel-nodirectediting": "Error message shown if the content model does not allow for direct editing. $1 is the localized name of the content model.",
 +      "changecontentmodel-emptymodels-title": "Title of the error page shown if the content model cannot be changed to any of the available types.",
 +      "changecontentmodel-emptymodels-text": "Text of the error page shown if the content model cannot be changed to any of the available types. $1 is the page title.",
        "log-name-contentmodel": "{{doc-logpage}}\n\nTitle of [[Special:Log/contentmodel]].",
        "log-description-contentmodel": "Text in [[Special:Log/contentmodel]].",
        "logentry-contentmodel-new": "{{Logentry}}\n$4 is not used.\n$5 is the new content model.",
        "whatlinkshere-prev": "This is part of the navigation message on the top and bottom of Whatlinkshere pages, where it is used as the first argument of {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - the number of items shown per page. It is not used when $1 is zero; not sure what happens when $1 is one.\nSpecial pages use {{msg-mw|Prevn}} instead (still as an argument to {{msg-mw|Viewprevnext}}).\n\nSee also:\n* {{msg-mw|Whatlinkshere-next}}\n{{Identical|Previous}}",
        "whatlinkshere-next": "This is part of the navigation message on the top and bottom of Whatlinkshere pages, where it is used as the second argument of {{msg-mw|Viewprevnext}}.\n\nParameters:\n* $1 - the number of items shown per page. It is not used when $1 is zero; not sure what happens when $1 is one.\nSpecial pages use {{msg-mw|Nextn}} instead (still as an argument to {{msg-mw|Viewprevnext}}).\n\nSee also:\n* {{msg-mw|Whatlinkshere-prev}}\n{{Identical|Next}}",
        "whatlinkshere-links": "Used on [[Special:WhatLinksHere]]. It is a link to the WhatLinksHere page of that page.\n\nExample line:\n* [[Main Page]] ([[Special:WhatLinksHere/Main Page|{{int:whatlinkshere-links}}]])\n{{Identical|Link}}",
 -      "whatlinkshere-hideredirs": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Redirect}}",
 -      "whatlinkshere-hidetrans": "First filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Transclusion}}",
 -      "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}\n{{Identical|Link}}",
 +      "whatlinkshere-hideredirs": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
 +      "whatlinkshere-hidetrans": "First filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
 +      "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
        "whatlinkshere-hideimages": "Filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 - the {{msg-mw|Hide}} or {{msg-mw|Show}}\n\nSee also:\n*{{msg-mw|Isimage}}\n*{{msg-mw|Media tip}}",
        "whatlinkshere-filters": "{{Identical|Filter}}",
        "whatlinkshere-submit": "Label for submit button in [[Special:WhatLinksHere]]\n{{Identical|Go}}",
        "unlockdbsuccesssub": "Used as subtitle in [[Special:UnlockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
        "lockdbsuccesstext": "Used as message text in [[Special:LockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
        "unlockdbsuccesstext": "Used as message text in [[Special:UnlockDB]].\n\nSee also:\n* {{msg-mw|Lockdbsuccesssub|subtitle}}\n* {{msg-mw|Lockdbsuccesstext|text}}\n* {{msg-mw|Unlockdbsuccesssub|subtitle}}\n* {{msg-mw|Unlockdbsuccesstext|text}}",
 -      "lockfilenotwritable": "'No longer needed' on wikipedia.",
 +      "lockfilenotwritable": "Used as error message in [[Special:LockDB]].",
 +      "databaselocked": "Used as error message in [[Special:LockDB]].\nThe title of this error message is {{msg-mw|Lockdb}}.\n\nSee also:\n* {{msg-mw|Lockdb|title}}\n* {{msg-mw|Databaselocked|message}}",
        "databasenotlocked": "Used as error message in [[Special:UnlockDB]].\nThe title of this error message is {{msg-mw|Lockdb}}.\n\nSee also:\n* {{msg-mw|Lockdb|title}}\n* {{msg-mw|Databasenotlocked|message}}",
        "lockedbyandtime": "Used as part of the message when a database is locked through [[Special:LockDB]]. Parameters:\n* $1 is the user that locked the database.\n* $2 is the date on which the lock was made\n* $3 is the time at which the lock was made",
        "move-page": "Used as page title of [[Special:MovePage]] to move pages.\n\nSee example: [[Special:MovePage/Portal:En]].\n\nParameters:\n* $1 - the name of the page to be moved (without link)\n{{Identical|Move}}",
        "variantname-gan": "{{Optional}}\n\nVariant option for wikis with variants conversion enabled.",
        "variantname-sr-ec": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-ec</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-cyrl</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
        "variantname-sr-el": "{{optional}}\nVariant Option for wikis with variants conversion enabled.\n\nNote that <code>sr-el</code> is not a conforming BCP47 language tag. Wikis should be migrated by:\n* allowing it only as a legacy alias of the preferred tag <code>sr-latn</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),\n* making the new tag the default to look first, before looking for the old tag,\n* moving the translations to the new code by renaming them,\n* checking links in source pages still using the legacy tag to change it to the new tag,\n* possibly cleanup the redirect pages.",
 -      "variantname-sr": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
 +      "variantname-sr": "{{optional}}\nVariant Option for wikis with variants conversion enabled.",
        "variantname-kk-kz": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "variantname-kk-tr": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "variantname-kk-cn": "{{optional}}\nVarient Option for wikis with variants conversion enabled.",
        "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.\n{{Identical|User agent}}",
        "searchsuggest-search": "Greyed out default text in the simple search box in the Vector skin. (It disappears and lets the user enter the requested search terms when the search box receives focus.)\n\n{{Identical|Search}}",
        "searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.",
 -      "api-error-autoblocked": "API error message that can be used for client side localisation of API errors.",
 +      "api-error-autoblocked": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Autoblockedtext}}.",
        "api-error-badaccess-groups": "API error message that can be used for client side localisation of API errors.",
        "api-error-badtoken": "API error message that can be used for client side localisation of API errors.",
        "api-error-blocked": "API error message that can be used for client side localisation of API errors.",
        "api-error-nomodule": "API error message that can be used for client side localisation of API errors.",
        "api-error-ok-but-empty": "API error message that can be used for client side localisation of API errors.",
        "api-error-overwrite": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-ratelimited": "API error message that can be used for client side localisation of API errors.",
 +      "api-error-ratelimited": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Actionthrottledtext}}",
        "api-error-stashfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-publishfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-stasherror": "API error message that can be used for client side localisation of API errors.",