MediaWiki
REL1_24
|
00001 <?php 00027 class UserCache { 00028 protected $cache = array(); // (uid => property => value) 00029 protected $typesCached = array(); // (uid => cache type => 1) 00030 00034 public static function singleton() { 00035 static $instance = null; 00036 if ( $instance === null ) { 00037 $instance = new self(); 00038 } 00039 00040 return $instance; 00041 } 00042 00043 protected function __construct() { 00044 } 00045 00053 public function getProp( $userId, $prop ) { 00054 if ( !isset( $this->cache[$userId][$prop] ) ) { 00055 wfDebug( __METHOD__ . ": querying DB for prop '$prop' for user ID '$userId'.\n" ); 00056 $this->doQuery( array( $userId ) ); // cache miss 00057 } 00058 00059 return isset( $this->cache[$userId][$prop] ) 00060 ? $this->cache[$userId][$prop] 00061 : false; // user does not exist? 00062 } 00063 00072 public function getUserName( $userId, $ip ) { 00073 return $userId > 0 ? $this->getProp( $userId, 'name' ) : $ip; 00074 } 00075 00082 public function doQuery( array $userIds, $options = array(), $caller = '' ) { 00083 wfProfileIn( __METHOD__ ); 00084 00085 $usersToCheck = array(); 00086 $usersToQuery = array(); 00087 00088 $userIds = array_unique( $userIds ); 00089 00090 foreach ( $userIds as $userId ) { 00091 $userId = (int)$userId; 00092 if ( $userId <= 0 ) { 00093 continue; // skip anons 00094 } 00095 if ( isset( $this->cache[$userId]['name'] ) ) { 00096 $usersToCheck[$userId] = $this->cache[$userId]['name']; // already have name 00097 } else { 00098 $usersToQuery[] = $userId; // we need to get the name 00099 } 00100 } 00101 00102 // Lookup basic info for users not yet loaded... 00103 if ( count( $usersToQuery ) ) { 00104 $dbr = wfGetDB( DB_SLAVE ); 00105 $table = array( 'user' ); 00106 $conds = array( 'user_id' => $usersToQuery ); 00107 $fields = array( 'user_name', 'user_real_name', 'user_registration', 'user_id' ); 00108 00109 $comment = __METHOD__; 00110 if ( strval( $caller ) !== '' ) { 00111 $comment .= "/$caller"; 00112 } 00113 00114 $res = $dbr->select( $table, $fields, $conds, $comment ); 00115 foreach ( $res as $row ) { // load each user into cache 00116 $userId = (int)$row->user_id; 00117 $this->cache[$userId]['name'] = $row->user_name; 00118 $this->cache[$userId]['real_name'] = $row->user_real_name; 00119 $this->cache[$userId]['registration'] = $row->user_registration; 00120 $usersToCheck[$userId] = $row->user_name; 00121 } 00122 } 00123 00124 $lb = new LinkBatch(); 00125 foreach ( $usersToCheck as $userId => $name ) { 00126 if ( $this->queryNeeded( $userId, 'userpage', $options ) ) { 00127 $lb->add( NS_USER, str_replace( ' ', '_', $row->user_name ) ); 00128 $this->typesCached[$userId]['userpage'] = 1; 00129 } 00130 if ( $this->queryNeeded( $userId, 'usertalk', $options ) ) { 00131 $lb->add( NS_USER_TALK, str_replace( ' ', '_', $row->user_name ) ); 00132 $this->typesCached[$userId]['usertalk'] = 1; 00133 } 00134 } 00135 $lb->execute(); 00136 00137 wfProfileOut( __METHOD__ ); 00138 } 00139 00148 protected function queryNeeded( $uid, $type, array $options ) { 00149 return ( in_array( $type, $options ) && !isset( $this->typesCached[$uid][$type] ) ); 00150 } 00151 }