MediaWiki REL1_37
GenderCache.php
Go to the documentation of this file.
1<?php
30
37 protected $cache = [];
38 protected $default;
39 protected $misses = 0;
40 protected $missLimit = 1000;
41
43 private $nsInfo;
44
47
50
51 public function __construct(
52 NamespaceInfo $nsInfo = null,
53 ILoadBalancer $loadBalancer = null,
55 ) {
56 $this->nsInfo = $nsInfo ?? MediaWikiServices::getInstance()->getNamespaceInfo();
57 $this->loadBalancer = $loadBalancer;
58 $this->userOptionsLookup = $userOptionsLookup ?? MediaWikiServices::getInstance()->getUserOptionsLookup();
59 }
60
65 protected function getDefault() {
66 if ( $this->default === null ) {
67 $this->default = $this->userOptionsLookup->getDefaultOption( 'gender' );
68 }
69
70 return $this->default;
71 }
72
79 public function getGenderOf( $username, $caller = '' ) {
80 if ( $username instanceof UserIdentity ) {
81 $username = $username->getName();
82 }
83
84 $username = self::normalizeUsername( $username );
85 if ( !isset( $this->cache[$username] ) ) {
86 if ( $this->misses >= $this->missLimit &&
87 RequestContext::getMain()->getUser()->getName() !== $username
88 ) {
89 if ( $this->misses === $this->missLimit ) {
90 $this->misses++;
91 wfDebug( __METHOD__ . ": too many misses, returning default onwards" );
92 }
93
94 return $this->getDefault();
95 } else {
96 $this->misses++;
97 $this->doQuery( $username, $caller );
98 }
99 }
100
101 /* Undefined if there is a valid username which for some reason doesn't
102 * exist in the database.
103 */
104 return $this->cache[$username] ?? $this->getDefault();
105 }
106
113 public function doLinkBatch( $data, $caller = '' ) {
114 $users = [];
115 foreach ( $data as $ns => $pagenames ) {
116 if ( !$this->nsInfo->hasGenderDistinction( $ns ) ) {
117 continue;
118 }
119 foreach ( array_keys( $pagenames ) as $username ) {
120 $users[$username] = true;
121 }
122 }
123
124 $this->doQuery( array_keys( $users ), $caller );
125 }
126
134 public function doTitlesArray( $titles, $caller = '' ) {
135 $users = [];
136 foreach ( $titles as $titleObj ) {
137 if ( !$this->nsInfo->hasGenderDistinction( $titleObj->getNamespace() ) ) {
138 continue;
139 }
140 $users[] = $titleObj->getText();
141 }
142
143 $this->doQuery( $users, $caller );
144 }
145
151 public function doQuery( $users, $caller = '' ) {
152 $default = $this->getDefault();
153
154 $usersToCheck = [];
155 foreach ( (array)$users as $value ) {
156 $name = self::normalizeUsername( $value );
157 // Skip users whose gender setting we already know
158 if ( !isset( $this->cache[$name] ) ) {
159 // For existing users, this value will be overwritten by the correct value
160 $this->cache[$name] = $default;
161 // We no longer verify that only valid names are checked for, T267054
162 $usersToCheck[] = $name;
163 }
164 }
165
166 if ( count( $usersToCheck ) === 0 ) {
167 return;
168 }
169
170 // Only query database, when load balancer is provided by service wiring
171 // This maybe not happen when running as part of the installer
172 if ( $this->loadBalancer === null ) {
173 return;
174 }
175
176 $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
177 $table = [ 'user', 'user_properties' ];
178 $fields = [ 'user_name', 'up_value' ];
179 $conds = [ 'user_name' => $usersToCheck ];
180 $joins = [ 'user_properties' =>
181 [ 'LEFT JOIN', [ 'user_id = up_user', 'up_property' => 'gender' ] ] ];
182
183 $comment = __METHOD__;
184 if ( strval( $caller ) !== '' ) {
185 $comment .= "/$caller";
186 }
187 $res = $dbr->select( $table, $fields, $conds, $comment, [], $joins );
188
189 foreach ( $res as $row ) {
190 $this->cache[$row->user_name] = $row->up_value ?: $default;
191 }
192 }
193
194 private static function normalizeUsername( $username ) {
195 // Strip off subpages
196 $indexSlash = strpos( $username, '/' );
197 if ( $indexSlash !== false ) {
198 $username = substr( $username, 0, $indexSlash );
199 }
200
201 // normalize underscore/spaces
202 return strtr( $username, '_', ' ' );
203 }
204}
UserOptionsLookup $userOptionsLookup
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Caches user genders when needed to use correct namespace aliases.
__construct(NamespaceInfo $nsInfo=null, ILoadBalancer $loadBalancer=null, UserOptionsLookup $userOptionsLookup=null)
getGenderOf( $username, $caller='')
Returns the gender for given username.
static normalizeUsername( $username)
NamespaceInfo $nsInfo
UserOptionsLookup $userOptionsLookup
doLinkBatch( $data, $caller='')
Wrapper for doQuery that processes raw LinkBatch data.
getDefault()
Returns the default gender option in this wiki.
ILoadBalancer null $loadBalancer
doTitlesArray( $titles, $caller='')
Wrapper for doQuery that processes a title array.
doQuery( $users, $caller='')
Preloads genders for given list of users.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Provides access to user options.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Interface for objects representing user identity.
Database cluster connection, tracking, load balancing, and transaction manager interface.
$cache
Definition mcc.php:33
const DB_REPLICA
Definition defines.php:25