Define which SpecialPage classes expect write vs read mode
authorAaron Schulz <aschulz@wikimedia.org>
Thu, 14 Jan 2016 22:35:31 +0000 (14:35 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 14 Jan 2016 22:40:37 +0000 (14:40 -0800)
Bug: T123591
Change-Id: I521ebdd5e8eb8f7f4df927dc38732170aef2ac19

30 files changed:
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialBlock.php
includes/specials/SpecialChangeContentModel.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialConfirmemail.php
includes/specials/SpecialCreateAccount.php
includes/specials/SpecialEditTags.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialEmailInvalidate.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialImport.php
includes/specials/SpecialLockdb.php
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialPreferences.php
includes/specials/SpecialResetTokens.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialRunJobs.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUnlockdb.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialUserlogout.php
includes/specials/SpecialUserrights.php

index 65a4eb9..0417146 100644 (file)
@@ -675,6 +675,16 @@ class SpecialPage {
                return $group;
        }
 
+       /**
+        * Indicates whether this special page may perform database writes
+        *
+        * @return bool
+        * @since 1.27
+        */
+       public function doesWrites() {
+               return false;
+       }
+
        /**
         * Under which header this special page is listed in Special:SpecialPages
         * See messages 'specialpages-group-*' for valid names
index 4bfe06d..2bb92bc 100644 (file)
@@ -500,7 +500,6 @@ class SpecialPageFactory {
         * @return bool
         */
        public static function executePath( Title &$title, IContextSource &$context, $including = false ) {
-
                // @todo FIXME: Redirects broken due to this call
                $bits = explode( '/', $title->getDBkey(), 2 );
                $name = $bits[0];
@@ -509,8 +508,8 @@ class SpecialPageFactory {
                } else {
                        $par = $bits[1];
                }
+
                $page = self::getPage( $name );
-               // Nonexistent?
                if ( !$page ) {
                        $context->getOutput()->setArticleRelated( false );
                        $context->getOutput()->setRobotPolicy( 'noindex,nofollow' );
@@ -525,6 +524,15 @@ class SpecialPageFactory {
                        return false;
                }
 
+               if ( !$including ) {
+                       // Narrow DB query expectations for this HTTP request
+                       $trxLimits = $context->getConfig()->get( 'TrxProfilerLimits' );
+                       $trxProfiler = Profiler::instance()->getTransactionProfiler();
+                       if ( $context->getRequest()->wasPosted() && !$page->doesWrites() ) {
+                               $trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
+                       }
+               }
+
                // Page exists, set the context
                $page->setContext( $context );
 
index f10c6e1..d198ea1 100644 (file)
@@ -51,6 +51,10 @@ class SpecialBlock extends FormSpecialPage {
                parent::__construct( 'Block', 'block' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Checks that the user can unblock themselves if they are trying to do so
         *
index 4812c9d..a9a7f97 100644 (file)
@@ -6,6 +6,10 @@ class SpecialChangeContentModel extends FormSpecialPage {
                parent::__construct( 'ChangeContentModel', 'editcontentmodel' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * @var Title|null
         */
index 51b08f9..989bae9 100644 (file)
@@ -36,6 +36,10 @@ class SpecialChangeEmail extends FormSpecialPage {
                parent::__construct( 'ChangeEmail', 'editmyprivateinfo' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * @return bool
         */
index 371ad19..8656798 100644 (file)
@@ -41,6 +41,10 @@ class SpecialChangePassword extends FormSpecialPage {
                $this->listed( false );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Main execution point
         * @param string|null $par
index 37d3636..5ed33e0 100644 (file)
@@ -34,6 +34,10 @@ class EmailConfirmation extends UnlistedSpecialPage {
                parent::__construct( 'Confirmemail', 'editmyprivateinfo' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Main execution point
         *
index 30e3833..f8c6832 100644 (file)
@@ -37,6 +37,10 @@ class SpecialCreateAccount extends SpecialRedirectToSpecial {
                );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        // No reason to hide this link on Special:Specialpages
        public function isListed() {
                return true;
index 97b04c2..916ba6b 100644 (file)
@@ -55,6 +55,10 @@ class SpecialEditTags extends UnlistedSpecialPage {
                parent::__construct( 'EditTags', 'changetags' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par ) {
                $this->checkPermissions();
                $this->checkReadOnly();
index 952ae0e..13ee8b3 100644 (file)
@@ -53,6 +53,10 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                parent::__construct( 'EditWatchlist', 'editmywatchlist' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Main execution point
         *
index 30f9d2e..b5c66ff 100644 (file)
@@ -32,6 +32,10 @@ class EmailInvalidation extends UnlistedSpecialPage {
                parent::__construct( 'Invalidateemail', 'editmyprivateinfo' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        function execute( $code ) {
                // Ignore things like master queries/connections on GET requests.
                // It's very convenient to just allow formless link usage.
index 618e700..c036d3d 100644 (file)
@@ -38,6 +38,10 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                parent::__construct( 'Emailuser' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function getDescription() {
                $target = self::getTarget( $this->mTarget );
                if ( !$target instanceof User ) {
index 5ca90ed..97e093b 100644 (file)
@@ -51,6 +51,10 @@ class SpecialImport extends SpecialPage {
                parent::__construct( 'Import', 'import' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Execute
         * @param string|null $par
index a276197..0d495a0 100644 (file)
@@ -33,6 +33,10 @@ class SpecialLockdb extends FormSpecialPage {
                parent::__construct( 'Lockdb', 'siteadmin' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function requiresWrite() {
                return false;
        }
index f11ed9a..2607330 100644 (file)
@@ -68,6 +68,10 @@ class SpecialMergeHistory extends SpecialPage {
                parent::__construct( 'MergeHistory', 'mergehistory' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * @return void
         */
index 0c0d929..4bdad79 100644 (file)
@@ -62,6 +62,10 @@ class MovePageForm extends UnlistedSpecialPage {
                parent::__construct( 'Movepage' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par ) {
                $this->useTransactionalTimeLimit();
 
index 7509bbc..69a9d48 100644 (file)
@@ -38,6 +38,10 @@ class SpecialPageLanguage extends FormSpecialPage {
                parent::__construct( 'PageLanguage', 'pagelang' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        protected function preText() {
                $this->getOutput()->addModules( 'mediawiki.special.pageLanguage' );
        }
index 292b575..21ce1e1 100644 (file)
@@ -51,6 +51,10 @@ class SpecialPasswordReset extends FormSpecialPage {
                parent::__construct( 'PasswordReset', 'editmyprivateinfo' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function userCanExecute( User $user ) {
                return $this->canChangePassword( $user ) === true && parent::userCanExecute( $user );
        }
index 3fa5fd5..965a36e 100644 (file)
@@ -31,6 +31,10 @@ class SpecialPreferences extends SpecialPage {
                parent::__construct( 'Preferences' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
index cba5a44..38e977b 100644 (file)
@@ -34,6 +34,10 @@ class SpecialResetTokens extends FormSpecialPage {
                parent::__construct( 'ResetTokens' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Returns the token information list for this page after running
         * the hook and filtering out disabled preferences.
index 6dcbcb1..44e44ba 100644 (file)
@@ -109,6 +109,10 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                parent::__construct( 'Revisiondelete', 'deletedhistory' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par ) {
                $this->useTransactionalTimeLimit();
 
index 4217553..eeaf2d3 100644 (file)
@@ -34,6 +34,10 @@ class SpecialRunJobs extends UnlistedSpecialPage {
                parent::__construct( 'RunJobs' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par = '' ) {
                $this->getOutput()->disable();
 
index f776832..cf807ef 100644 (file)
@@ -36,6 +36,10 @@ class SpecialUnblock extends SpecialPage {
                parent::__construct( 'Unblock', 'block' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function execute( $par ) {
                $this->checkPermissions();
                $this->checkReadOnly();
index 744a090..f99a52d 100644 (file)
@@ -51,6 +51,10 @@ class PageArchive {
                $this->config = $config;
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * List all deleted pages recorded in the archive table. Returns result
         * wrapper with (ar_namespace, ar_title, count) fields, ordered by page
index dc03a4a..b73e3c5 100644 (file)
@@ -32,6 +32,10 @@ class SpecialUnlockdb extends FormSpecialPage {
                parent::__construct( 'Unlockdb', 'siteadmin' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function requiresWrite() {
                return false;
        }
index b4470f5..5b3c43e 100644 (file)
@@ -38,6 +38,10 @@ class SpecialUpload extends SpecialPage {
                parent::__construct( 'Upload', 'upload' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /** Misc variables **/
 
        /** @var WebRequest|FauxRequest The request this form is supposed to handle */
index eb34008..1cec116 100644 (file)
@@ -52,6 +52,10 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                parent::__construct( 'UploadStash', 'upload' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Execute page -- can output a file directly or show a listing of them.
         *
index 620b55d..24e1675 100644 (file)
@@ -133,6 +133,10 @@ class LoginForm extends SpecialPage {
                $wgUseMediaWikiUIEverywhere = true;
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        /**
         * Returns an array of all valid error messages.
         *
index b79bf09..6e34690 100644 (file)
@@ -31,6 +31,10 @@ class SpecialUserlogout extends UnlistedSpecialPage {
                parent::__construct( 'Userlogout' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        function execute( $par ) {
                /**
                 * Some satellite ISPs use broken precaching schemes that log people out straight after
index cf94e50..01b1f8e 100644 (file)
@@ -41,6 +41,10 @@ class UserrightsPage extends SpecialPage {
                parent::__construct( 'Userrights' );
        }
 
+       public function doesWrites() {
+               return true;
+       }
+
        public function isRestricted() {
                return true;
        }