Merge "rc_old/new_len null for CategoryMembership RC change"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 18 Feb 2016 23:45:50 +0000 (23:45 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 18 Feb 2016 23:45:50 +0000 (23:45 +0000)
1  2 
includes/changes/EnhancedChangesList.php
includes/changes/RecentChange.php

@@@ -63,19 -63,19 +63,19 @@@ class EnhancedChangesList extends Chang
         * @return string
         */
        public function beginRecentChangesList() {
 -              $this->rc_cache = array();
 +              $this->rc_cache = [];
                $this->rcMoveIndex = 0;
                $this->rcCacheIndex = 0;
                $this->lastdate = '';
                $this->rclistOpen = false;
 -              $this->getOutput()->addModuleStyles( array(
 +              $this->getOutput()->addModuleStyles( [
                        'mediawiki.special.changeslist',
                        'mediawiki.special.changeslist.enhanced',
 -              ) );
 -              $this->getOutput()->addModules( array(
 +              ] );
 +              $this->getOutput()->addModules( [
                        'jquery.makeCollapsible',
                        'mediawiki.icon',
 -              ) );
 +              ] );
  
                return '<div class="mw-changeslist">';
        }
                if ( $date != $this->lastdate ) {
                        # Process current cache
                        $ret = $this->recentChangesBlock();
 -                      $this->rc_cache = array();
 +                      $this->rc_cache = [];
                        $ret .= Xml::element( 'h4', null, $date ) . "\n";
                        $this->lastdate = $date;
                }
                $cacheGroupingKey = $this->makeCacheGroupingKey( $cacheEntry );
  
                if ( !isset( $this->rc_cache[$cacheGroupingKey] ) ) {
 -                      $this->rc_cache[$cacheGroupingKey] = array();
 +                      $this->rc_cache[$cacheGroupingKey] = [];
                }
  
                array_push( $this->rc_cache[$cacheGroupingKey], $cacheEntry );
        protected function recentChangesBlockGroup( $block ) {
  
                # Add the namespace and title of the block as part of the class
 -              $tableClasses = array( 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc' );
 +              $tableClasses = [ 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc' ];
                if ( $block[0]->mAttribs['rc_log_type'] ) {
                        # Log entry
                        $tableClasses[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
                }
  
                # Collate list of users
 -              $userlinks = array();
 +              $userlinks = [];
                # Other properties
                $curId = 0;
                # Some catalyst variables...
                $namehidden = true;
                $allLogs = true;
                $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
 -              $collectedRcFlags = array(
 +              $collectedRcFlags = [
                        // All are by bots?
                        'bot' => true,
                        // Includes a new page?
                        'minor' => true,
                        // Contains an unpatrolled edit?
                        'unpatrolled' => false,
 -              );
 +              ];
                foreach ( $block as $rcObj ) {
                        if ( $rcObj->mAttribs['rc_type'] == RC_NEW ) {
                                $collectedRcFlags['newpage'] = true;
                # Sort the list and convert to text
                krsort( $userlinks );
                asort( $userlinks );
 -              $users = array();
 +              $users = [];
                foreach ( $userlinks as $userlink => $count ) {
                        $text = $userlink;
                        $text .= $this->getLanguage()->getDirMark();
                $queryParams['curid'] = $curId;
  
                # Sub-entries
 -              $lines = array();
 +              $lines = [];
                foreach ( $block as $i => $rcObj ) {
                        $line = $this->getLineData( $block, $rcObj, $queryParams );
                        if ( !$line ) {
                if ( $RCShowChangedSize && !$allLogs ) {
                        $last = 0;
                        $first = count( $block ) - 1;
-                       # Some events (like logs) have an "empty" size, so we need to skip those...
-                       while ( $last < $first && $block[$last]->mAttribs['rc_new_len'] === null ) {
+                       # Some events (like logs and category changes) have an "empty" size, so we need to skip those...
+                       while ( $last < $first && (
+                                       $block[$last]->mAttribs['rc_new_len'] === null ||
+                                       # TODO kill the below check after March 2016 - https://phabricator.wikimedia.org/T126428
+                                       $block[$last]->mAttribs['rc_type'] == RC_CATEGORIZE
+                               ) ) {
                                $last++;
                        }
-                       while ( $first > $last && $block[$first]->mAttribs['rc_old_len'] === null ) {
+                       while ( $last < $first && (
+                                       $block[$first]->mAttribs['rc_old_len'] === null ||
+                                       # TODO kill the below check after March 2016 - https://phabricator.wikimedia.org/T126428
+                                       $block[$first]->mAttribs['rc_type'] == RC_CATEGORIZE
+                               ) ) {
                                $first--;
                        }
                        # Get net change
                        implode( $this->message['semicolon-separator'], $users )
                )->escaped();
  
 -              $templateParams = array(
 +              $templateParams = [
                        'articleLink' => $articleLink,
                        'charDifference' => $charDifference,
                        'collectedRcFlags' => $this->recentChangesFlags( $collectedRcFlags ),
                        'tableClasses' => $tableClasses,
                        'timestamp' => $block[0]->timestamp,
                        'users' => $usersList,
 -              );
 +              ];
  
                $this->rcCacheIndex++;
  
         * @throws FatalError
         * @throws MWException
         */
 -      protected function getLineData( array $block, RCCacheEntry $rcObj, array $queryParams = array() ) {
 +      protected function getLineData( array $block, RCCacheEntry $rcObj, array $queryParams = [] ) {
                $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
  
                # Classes to apply -- TODO implement
 -              $classes = array();
 +              $classes = [];
                $type = $rcObj->mAttribs['rc_type'];
 -              $data = array();
 -              $lineParams = array();
 +              $data = [];
 +              $lineParams = [];
  
                if ( $rcObj->watched
                        && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched
                ) {
 -                      $lineParams['classes'] = array( 'mw-enhanced-watched' );
 +                      $lineParams['classes'] = [ 'mw-enhanced-watched' ];
                }
                $separator = ' <span class="mw-changeslist-separator">. .</span> ';
  
 -              $data['recentChangesFlags'] = array(
 +              $data['recentChangesFlags'] = [
                        'newpage' => $type == RC_NEW,
                        'minor' => $rcObj->mAttribs['rc_minor'],
                        'unpatrolled' => $rcObj->unpatrolled,
                        'bot' => $rcObj->mAttribs['rc_bot'],
 -              );
 +              ];
  
                $params = $queryParams;
  
                        $link = Linker::linkKnown(
                                $rcObj->getTitle(),
                                $rcObj->timestamp,
 -                              array(),
 +                              [],
                                $params
                        );
                        if ( $this->isDeleted( $rcObj, Revision::DELETED_TEXT ) ) {
  
                // give the hook a chance to modify the data
                $success = Hooks::run( 'EnhancedChangesListModifyLineData',
 -                      array( $this, &$data, $block, $rcObj ) );
 +                      [ $this, &$data, $block, $rcObj ] );
                if ( !$success ) {
                        // skip entry if hook aborted it
 -                      return array();
 +                      return [];
                }
  
                if ( isset( $data['recentChangesFlags'] ) ) {
                }
  
                # Changes message
 -              static $nchanges = array();
 -              static $sinceLastVisitMsg = array();
 +              static $nchanges = [];
 +              static $sinceLastVisitMsg = [];
  
                $n = count( $block );
                if ( !isset( $nchanges[$n] ) ) {
                }
  
                # Total change link
 -              $links = array();
 +              $links = [];
                /** @var $block0 RecentChange */
                $block0 = $block[0];
                $last = $block[count( $block ) - 1];
                                $links['total-changes'] = Linker::link(
                                        $block0->getTitle(),
                                        $nchanges[$n],
 -                                      array(),
 -                                      $queryParams + array(
 +                                      [],
 +                                      $queryParams + [
                                                'diff' => $currentRevision,
                                                'oldid' => $last->mAttribs['rc_last_oldid'],
 -                                      ),
 -                                      array( 'known', 'noclasses' )
 +                                      ],
 +                                      [ 'known', 'noclasses' ]
                                );
                                if ( $sinceLast > 0 && $sinceLast < $n ) {
                                        $links['total-changes-since-last'] = Linker::link(
                                                        $block0->getTitle(),
                                                        $sinceLastVisitMsg[$sinceLast],
 -                                                      array(),
 -                                                      $queryParams + array(
 +                                                      [],
 +                                                      $queryParams + [
                                                                'diff' => $currentRevision,
                                                                'oldid' => $unvisitedOldid,
 -                                                      ),
 -                                                      array( 'known', 'noclasses' )
 +                                                      ],
 +                                                      [ 'known', 'noclasses' ]
                                                );
                                }
                        }
                        $links['history'] = Linker::linkKnown(
                                        $block0->getTitle(),
                                        $this->message['enhancedrc-history'],
 -                                      array(),
 +                                      [],
                                        $params
                                );
                }
  
                # Allow others to alter, remove or add to these links
                Hooks::run( 'EnhancedChangesList::getLogText',
 -                      array( $this, &$links, $block ) );
 +                      [ $this, &$links, $block ] );
  
                if ( !$links ) {
                        return '';
         * @return string A HTML formatted line (generated using $r)
         */
        protected function recentChangesBlockLine( $rcObj ) {
 -              $data = array();
 +              $data = [];
  
                $query['curid'] = $rcObj->mAttribs['rc_cur_id'];
  
                $type = $rcObj->mAttribs['rc_type'];
                $logType = $rcObj->mAttribs['rc_log_type'];
 -              $classes = array( 'mw-enhanced-rc' );
 +              $classes = [ 'mw-enhanced-rc' ];
                if ( $logType ) {
                        # Log entry
                        $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType );
                        ? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
  
                # Flag and Timestamp
 -              $data['recentChangesFlags'] = array(
 +              $data['recentChangesFlags'] = [
                        'newpage' => $type == RC_NEW,
                        'minor' => $rcObj->mAttribs['rc_minor'],
                        'unpatrolled' => $rcObj->unpatrolled,
                        'bot' => $rcObj->mAttribs['rc_bot'],
 -              );
 +              ];
                // timestamp is not really a link here, but is called timestampLink
                // for consistency with EnhancedChangesListModifyLineData
                $data['timestampLink'] = $rcObj->timestamp;
  
                // give the hook a chance to modify the data
                $success = Hooks::run( 'EnhancedChangesListModifyBlockLineData',
 -                      array( $this, &$data, $rcObj ) );
 +                      [ $this, &$data, $rcObj ] );
                if ( !$success ) {
                        // skip entry if hook aborted it
                        return '';
                }
  
 -              $line = Html::openElement( 'table', array( 'class' => $classes ) ) .
 +              $line = Html::openElement( 'table', [ 'class' => $classes ] ) .
                        Html::openElement( 'tr' );
                $line .= '<td class="mw-enhanced-rc"><span class="mw-enhancedchanges-arrow-space"></span>';
  
                                ->rawParams( $rc->difflink . $this->message['pipe-separator'] . Linker::linkKnown(
                                                $pageTitle,
                                                $this->message['hist'],
 -                                              array(),
 +                                              [],
                                                $query
                                        ) )->escaped();
                return $retVal;
@@@ -69,8 -69,8 +69,8 @@@ class RecentChange 
        const SRC_EXTERNAL = 'mw.external'; // obsolete
        const SRC_CATEGORIZE = 'mw.categorize';
  
 -      public $mAttribs = array();
 -      public $mExtra = array();
 +      public $mAttribs = [];
 +      public $mExtra = [];
  
        /**
         * @var Title
        /**
         * @var array Array of change types
         */
 -      private static $changeTypes = array(
 +      private static $changeTypes = [
                'edit' => RC_EDIT,
                'new' => RC_NEW,
                'log' => RC_LOG,
                'external' => RC_EXTERNAL,
                'categorize' => RC_CATEGORIZE,
 -      );
 +      ];
  
        # Factory methods
  
         */
        public static function parseToRCType( $type ) {
                if ( is_array( $type ) ) {
 -                      $retval = array();
 +                      $retval = [];
                        foreach ( $type as $t ) {
                                $retval[] = RecentChange::parseToRCType( $t );
                        }
         * @return RecentChange|null
         */
        public static function newFromId( $rcid ) {
 -              return self::newFromConds( array( 'rc_id' => $rcid ), __METHOD__ );
 +              return self::newFromConds( [ 'rc_id' => $rcid ], __METHOD__ );
        }
  
        /**
         * @return array
         */
        public static function selectFields() {
 -              return array(
 +              return [
                        'rc_id',
                        'rc_timestamp',
                        'rc_user',
                        'rc_log_type',
                        'rc_log_action',
                        'rc_params',
 -              );
 +              ];
        }
  
        # Accessors
  
                $dbw = wfGetDB( DB_MASTER );
                if ( !is_array( $this->mExtra ) ) {
 -                      $this->mExtra = array();
 +                      $this->mExtra = [];
                }
  
                if ( !$wgPutIPinRC ) {
                $this->mAttribs['rc_id'] = $dbw->insertId();
  
                # Notify extensions
 -              Hooks::run( 'RecentChange_save', array( &$this ) );
 +              Hooks::run( 'RecentChange_save', [ &$this ] );
  
                # Notify external application via UDP
                if ( !$noudp ) {
  
                        // Never send an RC notification email about categorization changes
                        if ( $this->mAttribs['rc_type'] != RC_CATEGORIZE ) {
 -                              if ( Hooks::run( 'AbortEmailNotification', array( $editor, $title, $this ) ) ) {
 +                              if ( Hooks::run( 'AbortEmailNotification', [ $editor, $title, $this ] ) ) {
                                        # @todo FIXME: This would be better as an extension hook
                                        $enotif = new EmailNotification();
                                        $enotif->notifyOnPageChange(
                $performer = $this->getPerformer();
  
                foreach ( $feeds as $feed ) {
 -                      $feed += array(
 +                      $feed += [
                                'omit_bots' => false,
                                'omit_anon' => false,
                                'omit_user' => false,
                                'omit_minor' => false,
                                'omit_patrolled' => false,
 -                      );
 +                      ];
  
                        if (
                                ( $feed['omit_bots'] && $this->mAttribs['rc_bot'] ) ||
         */
        public function doMarkPatrolled( User $user, $auto = false ) {
                global $wgUseRCPatrol, $wgUseNPPatrol, $wgUseFilePatrol;
 -              $errors = array();
 +              $errors = [];
                // If recentchanges patrol is disabled, only new pages or new file versions
                // can be patrolled, provided the appropriate config variable is set
                if ( !$wgUseRCPatrol && ( !$wgUseNPPatrol || $this->getAttribute( 'rc_type' ) != RC_NEW ) &&
                        ( !$wgUseFilePatrol || !( $this->getAttribute( 'rc_type' ) == RC_LOG &&
                        $this->getAttribute( 'rc_log_type' ) == 'upload' ) ) ) {
 -                      $errors[] = array( 'rcpatroldisabled' );
 +                      $errors[] = [ 'rcpatroldisabled' ];
                }
                // Automatic patrol needs "autopatrol", ordinary patrol needs "patrol"
                $right = $auto ? 'autopatrol' : 'patrol';
                $errors = array_merge( $errors, $this->getTitle()->getUserPermissionsErrors( $right, $user ) );
                if ( !Hooks::run( 'MarkPatrolled',
 -                                      array( $this->getAttribute( 'rc_id' ), &$user, false, $auto ) )
 +                                      [ $this->getAttribute( 'rc_id' ), &$user, false, $auto ] )
                ) {
 -                      $errors[] = array( 'hookaborted' );
 +                      $errors[] = [ 'hookaborted' ];
                }
                // Users without the 'autopatrol' right can't patrol their
                // own revisions
                if ( $user->getName() === $this->getAttribute( 'rc_user_text' )
                        && !$user->isAllowed( 'autopatrol' )
                ) {
 -                      $errors[] = array( 'markedaspatrollederror-noautopatrol' );
 +                      $errors[] = [ 'markedaspatrollederror-noautopatrol' ];
                }
                if ( $errors ) {
                        return $errors;
                }
                // If the change was patrolled already, do nothing
                if ( $this->getAttribute( 'rc_patrolled' ) ) {
 -                      return array();
 +                      return [];
                }
                // Actually set the 'patrolled' flag in RC
                $this->reallyMarkPatrolled();
                PatrolLog::record( $this, $auto, $user );
                Hooks::run(
                                        'MarkPatrolledComplete',
 -                                      array( $this->getAttribute( 'rc_id' ), &$user, false, $auto )
 +                                      [ $this->getAttribute( 'rc_id' ), &$user, false, $auto ]
                );
  
 -              return array();
 +              return [];
        }
  
        /**
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'recentchanges',
 -                      array(
 +                      [
                                'rc_patrolled' => 1
 -                      ),
 -                      array(
 +                      ],
 +                      [
                                'rc_id' => $this->getAttribute( 'rc_id' )
 -                      ),
 +                      ],
                        __METHOD__
                );
                // Invalidate the page cache after the page has been patrolled
         * @param int $newSize
         * @param int $newId
         * @param int $patrol
 +       * @param array $tags
         * @return RecentChange
         */
        public static function notifyEdit(
                $timestamp, &$title, $minor, &$user, $comment, $oldId, $lastTimestamp,
 -              $bot, $ip = '', $oldSize = 0, $newSize = 0, $newId = 0, $patrol = 0
 +              $bot, $ip = '', $oldSize = 0, $newSize = 0, $newId = 0, $patrol = 0,
 +              $tags = []
        ) {
                $rc = new RecentChange;
                $rc->mTitle = $title;
                $rc->mPerformer = $user;
 -              $rc->mAttribs = array(
 +              $rc->mAttribs = [
                        'rc_timestamp' => $timestamp,
                        'rc_namespace' => $title->getNamespace(),
                        'rc_title' => $title->getDBkey(),
                        'rc_log_type' => null,
                        'rc_log_action' => '',
                        'rc_params' => ''
 -              );
 +              ];
  
 -              $rc->mExtra = array(
 +              $rc->mExtra = [
                        'prefixedDBkey' => $title->getPrefixedDBkey(),
                        'lastTimestamp' => $lastTimestamp,
                        'oldSize' => $oldSize,
                        'newSize' => $newSize,
                        'pageStatus' => 'changed'
 -              );
 +              ];
  
 -              DeferredUpdates::addCallableUpdate( function() use ( $rc ) {
 +              DeferredUpdates::addCallableUpdate( function() use ( $rc, $tags ) {
                        $rc->save();
                        if ( $rc->mAttribs['rc_patrolled'] ) {
                                PatrolLog::record( $rc, true, $rc->getPerformer() );
                        }
 +                      if ( count( $tags ) ) {
 +                              ChangeTags::addTags( $tags, $rc->mAttribs['rc_id'],
 +                                      $rc->mAttribs['rc_this_oldid'], null, null );
 +                      }
                } );
  
                return $rc;
         * @param int $size
         * @param int $newId
         * @param int $patrol
 +       * @param array $tags
         * @return RecentChange
         */
        public static function notifyNew(
                $timestamp, &$title, $minor, &$user, $comment, $bot,
 -              $ip = '', $size = 0, $newId = 0, $patrol = 0
 +              $ip = '', $size = 0, $newId = 0, $patrol = 0, $tags = []
        ) {
                $rc = new RecentChange;
                $rc->mTitle = $title;
                $rc->mPerformer = $user;
 -              $rc->mAttribs = array(
 +              $rc->mAttribs = [
                        'rc_timestamp' => $timestamp,
                        'rc_namespace' => $title->getNamespace(),
                        'rc_title' => $title->getDBkey(),
                        'rc_log_type' => null,
                        'rc_log_action' => '',
                        'rc_params' => ''
 -              );
 +              ];
  
 -              $rc->mExtra = array(
 +              $rc->mExtra = [
                        'prefixedDBkey' => $title->getPrefixedDBkey(),
                        'lastTimestamp' => 0,
                        'oldSize' => 0,
                        'newSize' => $size,
                        'pageStatus' => 'created'
 -              );
 +              ];
  
 -              DeferredUpdates::addCallableUpdate( function() use ( $rc ) {
 +              DeferredUpdates::addCallableUpdate( function() use ( $rc, $tags ) {
                        $rc->save();
                        if ( $rc->mAttribs['rc_patrolled'] ) {
                                PatrolLog::record( $rc, true, $rc->getPerformer() );
                        }
 +                      if ( count( $tags ) ) {
 +                              ChangeTags::addTags( $tags, $rc->mAttribs['rc_id'],
 +                                      $rc->mAttribs['rc_this_oldid'], null, null );
 +                      }
                } );
  
                return $rc;
                $rc = new RecentChange;
                $rc->mTitle = $target;
                $rc->mPerformer = $user;
 -              $rc->mAttribs = array(
 +              $rc->mAttribs = [
                        'rc_timestamp' => $timestamp,
                        'rc_namespace' => $target->getNamespace(),
                        'rc_title' => $target->getDBkey(),
                        'rc_log_type' => $type,
                        'rc_log_action' => $action,
                        'rc_params' => $params
 -              );
 +              ];
  
 -              $rc->mExtra = array(
 +              $rc->mExtra = [
                        'prefixedDBkey' => $title->getPrefixedDBkey(),
                        'lastTimestamp' => 0,
                        'actionComment' => $actionComment, // the comment appended to the action, passed from LogPage
                        'pageStatus' => $pageStatus,
                        'actionCommentIRC' => $actionCommentIRC
 -              );
 +              ];
  
                return $rc;
        }
                $rc = new RecentChange;
                $rc->mTitle = $categoryTitle;
                $rc->mPerformer = $user;
 -              $rc->mAttribs = array(
 +              $rc->mAttribs = [
                        'rc_timestamp' => $timestamp,
                        'rc_namespace' => $categoryTitle->getNamespace(),
                        'rc_title' => $categoryTitle->getDBkey(),
                        'rc_ip' => self::checkIPAddress( $ip ),
                        'rc_patrolled' => 1, // Always patrolled, just like log entries
                        'rc_new' => 0, # obsolete
-                       'rc_old_len' => 0,
-                       'rc_new_len' => 0,
+                       'rc_old_len' => null,
+                       'rc_new_len' => null,
                        'rc_deleted' => $deleted,
                        'rc_logid' => 0,
                        'rc_log_type' => null,
                        'rc_log_action' => '',
                        'rc_params' => ''
 -              );
 +              ];
  
 -              $rc->mExtra = array(
 +              $rc->mExtra = [
                        'prefixedDBkey' => $categoryTitle->getPrefixedDBkey(),
                        'lastTimestamp' => $lastTimestamp,
                        'oldSize' => 0,
                        'newSize' => 0,
                        'pageStatus' => 'changed'
 -              );
 +              ];
  
                return $rc;
        }