Add batch lookup for user groups on Special:ListUsers
authorumherirrender <umherirrender_de.wp@web.de>
Fri, 7 Nov 2014 16:28:56 +0000 (17:28 +0100)
committerumherirrender <umherirrender_de.wp@web.de>
Sat, 20 Dec 2014 09:33:56 +0000 (10:33 +0100)
At the moment for each user on the list a new user object is created and
than the getGroups method is called, which fully init the user object,
which is done in 3 queries (user table, user_properties and
user_groups).
Removed the user object with one query for all the userids and cache the
result.

Also added the group page to the LinkBatch, because now the necessary
pages can be determined easily.

Change-Id: I4a945f83ad28edf5cc040139943cf743cb3d133c

includes/specials/SpecialListusers.php

index 68c5346..7669b5c 100644 (file)
  */
 class UsersPager extends AlphabeticPager {
 
+       /**
+        * @var array A array with user ids as key and a array of groups as value
+        */
+       private $userGroupCache;
+
        /**
         * @param IContextSource $context
         * @param array $par (Default null)
@@ -176,7 +181,7 @@ class UsersPager extends AlphabeticPager {
                $lang = $this->getLanguage();
 
                $groups = '';
-               $groups_list = self::getGroups( $row->user_id );
+               $groups_list = self::getGroups( intval( $row->user_id ), $this->userGroupCache );
 
                if ( !$this->including && count( $groups_list ) > 0 ) {
                        $list = array();
@@ -218,11 +223,38 @@ class UsersPager extends AlphabeticPager {
 
        function doBatchLookups() {
                $batch = new LinkBatch();
+               $userIds = array();
                # Give some pointers to make user links
                foreach ( $this->mResult as $row ) {
                        $batch->add( NS_USER, $row->user_name );
                        $batch->add( NS_USER_TALK, $row->user_name );
+                       $userIds[] = $row->user_id;
+               }
+
+               // Lookup groups for all the users
+               $dbr = wfGetDB( DB_SLAVE );
+               $groupRes = $dbr->select(
+                       'user_groups',
+                       array( 'ug_user', 'ug_group' ),
+                       array( 'ug_user' => $userIds ),
+                       __METHOD__
+               );
+               $cache = array();
+               $groups = array();
+               foreach ( $groupRes as $row ) {
+                       $cache[intval( $row->ug_user )][] = $row->ug_group;
+                       $groups[$row->ug_group] = true;
                }
+               $this->userGroupCache = $cache;
+
+               // Add page of groups to link batch
+               foreach( $groups as $group => $unused ) {
+                       $groupPage = User::getGroupPage( $group );
+                       if ( $groupPage ) {
+                               $batch->addObj( $groupPage );
+                       }
+               }
+
                $batch->execute();
                $this->mResult->rewind();
        }
@@ -331,11 +363,17 @@ class UsersPager extends AlphabeticPager {
         * Get a list of groups the specified user belongs to
         *
         * @param int $uid User id
+        * @param array|null $cache
         * @return array
         */
-       protected static function getGroups( $uid ) {
-               $user = User::newFromId( $uid );
-               $groups = array_diff( $user->getEffectiveGroups(), User::getImplicitGroups() );
+       protected static function getGroups( $uid, $cache = null ) {
+               if ( $cache === null ) {
+                       $user = User::newFromId( $uid );
+                       $effectiveGroups = $user->getEffectiveGroups();
+               } else {
+                       $effectiveGroups = isset( $cache[$uid] ) ? $cache[$uid] : array();
+               }
+               $groups = array_diff( $effectiveGroups, User::getImplicitGroups() );
 
                return $groups;
        }