Merge "Use WikiMap methods for wiki ID logic in more places"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 30 Oct 2018 07:20:29 +0000 (07:20 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 30 Oct 2018 07:20:29 +0000 (07:20 +0000)
1  2 
includes/debug/logger/LegacyLogger.php
includes/user/User.php

@@@ -22,6 -22,7 +22,7 @@@ namespace MediaWiki\Logger
  
  use DateTimeZone;
  use Exception;
+ use WikiMap;
  use MWDebug;
  use MWExceptionHandler;
  use Psr\Log\AbstractLogger;
@@@ -93,38 -94,18 +94,38 @@@ class LegacyLogger extends AbstractLogg
         * @return null
         */
        public function log( $level, $message, array $context = [] ) {
 +              global $wgDBerrorLog;
 +
                if ( is_string( $level ) ) {
                        $level = self::$levelMapping[$level];
                }
 -              if ( $this->channel === 'DBQuery' && isset( $context['method'] )
 -                      && isset( $context['master'] ) && isset( $context['runtime'] )
 +              if ( $this->channel === 'DBQuery'
 +                      && isset( $context['method'] )
 +                      && isset( $context['master'] )
 +                      && isset( $context['runtime'] )
                ) {
 -                      MWDebug::query( $message, $context['method'], $context['master'], $context['runtime'] );
 -                      return; // only send profiling data to MWDebug profiling
 +                      // Also give the query information to the MWDebug tools
 +                      $enabled = MWDebug::query(
 +                              $message,
 +                              $context['method'],
 +                              $context['master'],
 +                              $context['runtime']
 +                      );
 +                      if ( $enabled ) {
 +                              // If we the toolbar was enabled, return early so that we don't
 +                              // also log the query to the main debug output.
 +                              return;
 +                      }
                }
  
 +              // If this is a DB-related error, and the site has $wgDBerrorLog
 +              // configured, rewrite the channel as wfLogDBError instead.
 +              // Likewise, if the site does not use  $wgDBerrorLog, it should
 +              // configurable like any other channel via $wgDebugLogGroups
 +              // or $wgMWLoggerDefaultSpi.
                if ( isset( self::$dbChannels[$this->channel] )
                        && $level >= self::$levelMapping[LogLevel::ERROR]
 +                      && $wgDBerrorLog
                ) {
                        // Format and write DB errors to the legacy locations
                        $effectiveChannel = 'wfLogDBError';
                $date = $d->format( 'D M j G:i:s T Y' );
  
                $host = wfHostname();
-               $wiki = wfWikiID();
+               $wiki = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
  
                $text = "{$date}\t{$host}\t{$wiki}\t{$message}\n";
                return $text;
         */
        protected static function formatAsWfDebugLog( $channel, $message, $context ) {
                $time = wfTimestamp( TS_DB );
-               $wiki = wfWikiID();
+               $wiki = WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() );
                $host = wfHostname();
                $text = "{$time} {$host} {$wiki}: {$message}\n";
                return $text;
diff --combined includes/user/User.php
@@@ -1817,7 -1817,11 +1817,7 @@@ class User implements IDBAccessObject, 
         */
        public static function getDefaultOption( $opt ) {
                $defOpts = self::getDefaultOptions();
 -              if ( isset( $defOpts[$opt] ) ) {
 -                      return $defOpts[$opt];
 -              } else {
 -                      return null;
 -              }
 +              return $defOpts[$opt] ?? null;
        }
  
        /**
         * Check if user is blocked from editing a particular article
         *
         * @param Title $title Title to check
 -       * @param bool $bFromSlave Whether to check the replica DB instead of the master
 +       * @param bool $fromSlave Whether to check the replica DB instead of the master
         * @return bool
         */
 -      public function isBlockedFrom( $title, $bFromSlave = false ) {
 -              global $wgBlockAllowsUTEdit;
 +      public function isBlockedFrom( $title, $fromSlave = false ) {
 +              $blocked = $this->isHidden();
  
 -              $blocked = $this->isBlocked( $bFromSlave );
 -              $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk : false );
 -              // If a user's name is suppressed, they cannot make edits anywhere
 -              if ( !$this->mHideName && $allowUsertalk && $title->getText() === $this->getName()
 -                      && $title->getNamespace() == NS_USER_TALK ) {
 -                      $blocked = false;
 -                      wfDebug( __METHOD__ . ": self-talk page, ignoring any blocks\n" );
 +              if ( !$blocked ) {
 +                      $block = $this->getBlock( $fromSlave );
 +                      if ( $block ) {
 +                              $blocked = $block->preventsEdit( $title );
 +                      }
                }
  
 +              // only for the purpose of the hook. We really don't need this here.
 +              $allowUsertalk = $this->mAllowUsertalk;
 +
                Hooks::run( 'UserIsBlockedFrom', [ $this, $title, &$blocked, &$allowUsertalk ] );
  
                return $blocked;
         */
        public function isHidden() {
                if ( $this->mHideName !== null ) {
 -                      return $this->mHideName;
 +                      return (bool)$this->mHideName;
                }
                $this->getBlockedStatus();
                if ( !$this->mHideName ) {
                        $this->mHideName = $authUser && $authUser->isHidden();
                        Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] );
                }
 -              return $this->mHideName;
 +              return (bool)$this->mHideName;
        }
  
        /**
                        $this->isAnon() ? [ 'user_ip' => $this->getName() ] : [ 'user_id' => $this->getId() ],
                        __METHOD__ );
                $rev = $timestamp ? Revision::loadFromTimestamp( $dbr, $utp, $timestamp ) : null;
-               return [ [ 'wiki' => wfWikiID(), 'link' => $utp->getLocalURL(), 'rev' => $rev ] ];
+               return [
+                       [
+                               'wiki' => WikiMap::getWikiIdFromDomain( WikiMap::getCurrentWikiDomain() ),
+                               'link' => $utp->getLocalURL(),
+                               'rev' => $rev
+                       ]
+               ];
        }
  
        /**
  
                        if ( $count === null ) {
                                // it has not been initialized. do so.
 -                              $count = $this->initEditCount();
 +                              $count = $this->initEditCountInternal();
                        }
                        $this->mEditCount = $count;
                }
                return $this->mBlock && $this->mBlock->prevents( 'sendemail' );
        }
  
 +      /**
 +       * Get whether the user is blocked from using Special:Upload
 +       *
 +       * @return bool
 +       */
 +      public function isBlockedFromUpload() {
 +              $this->getBlockedStatus();
 +              return $this->mBlock && $this->mBlock->prevents( 'upload' );
 +      }
 +
        /**
         * Get whether the user is allowed to create an account.
         * @return bool
        }
  
        /**
 -       * Deferred version of incEditCountImmediate()
 -       *
 -       * This function, rather than incEditCountImmediate(), should be used for
 -       * most cases as it avoids potential deadlocks caused by concurrent editing.
 +       * Schedule a deferred update to update the user's edit count
         */
        public function incEditCount() {
 -              wfGetDB( DB_MASTER )->onTransactionPreCommitOrIdle(
 -                      function () {
 -                              $this->incEditCountImmediate();
 -                      },
 -                      __METHOD__
 +              if ( $this->isAnon() ) {
 +                      return; // sanity
 +              }
 +
 +              DeferredUpdates::addUpdate(
 +                      new UserEditCountUpdate( $this, 1 ),
 +                      DeferredUpdates::POSTSEND
                );
        }
  
        /**
 -       * Increment the user's edit-count field.
 -       * Will have no effect for anonymous users.
 -       * @since 1.26
 +       * This method should not be called outside User/UserEditCountUpdate
 +       *
 +       * @param int $count
         */
 -      public function incEditCountImmediate() {
 -              if ( $this->isAnon() ) {
 -                      return;
 -              }
 -
 -              $dbw = wfGetDB( DB_MASTER );
 -              // No rows will be "affected" if user_editcount is NULL
 -              $dbw->update(
 -                      'user',
 -                      [ 'user_editcount=user_editcount+1' ],
 -                      [ 'user_id' => $this->getId(), 'user_editcount IS NOT NULL' ],
 -                      __METHOD__
 -              );
 -              // Lazy initialization check...
 -              if ( $dbw->affectedRows() == 0 ) {
 -                      // Now here's a goddamn hack...
 -                      $dbr = wfGetDB( DB_REPLICA );
 -                      if ( $dbr !== $dbw ) {
 -                              // If we actually have a replica DB server, the count is
 -                              // at least one behind because the current transaction
 -                              // has not been committed and replicated.
 -                              $this->mEditCount = $this->initEditCount( 1 );
 -                      } else {
 -                              // But if DB_REPLICA is selecting the master, then the
 -                              // count we just read includes the revision that was
 -                              // just added in the working transaction.
 -                              $this->mEditCount = $this->initEditCount();
 -                      }
 -              } else {
 -                      if ( $this->mEditCount === null ) {
 -                              $this->getEditCount();
 -                              $dbr = wfGetDB( DB_REPLICA );
 -                              $this->mEditCount += ( $dbr !== $dbw ) ? 1 : 0;
 -                      } else {
 -                              $this->mEditCount++;
 -                      }
 -              }
 -              // Edit count in user cache too
 -              $this->invalidateCache();
 +      public function setEditCountInternal( $count ) {
 +              $this->mEditCount = $count;
        }
  
        /**
         * Initialize user_editcount from data out of the revision table
         *
 -       * @param int $add Edits to add to the count from the revision table
 +       * This method should not be called outside User/UserEditCountUpdate
 +       *
         * @return int Number of edits
         */
 -      protected function initEditCount( $add = 0 ) {
 +      public function initEditCountInternal() {
                // Pull from a replica DB to be less cruel to servers
                // Accuracy isn't the point anyway here
                $dbr = wfGetDB( DB_REPLICA );
                        [],
                        $actorWhere['joins']
                );
 -              $count = $count + $add;
  
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'user',
                        [ 'user_editcount' => $count ],
 -                      [ 'user_id' => $this->getId() ],
 +                      [
 +                              'user_id' => $this->getId(),
 +                              'user_editcount IS NULL OR user_editcount < ' . (int)$count
 +                      ],
                        __METHOD__
                );