MediaWiki REL1_39
GenderCache.php
Go to the documentation of this file.
1<?php
27
35 protected $cache = [];
36 protected $default;
37 protected $misses = 0;
38 protected $missLimit = 1000;
39
41 private $nsInfo;
42
44 private $loadBalancer;
45
47 private $userOptionsLookup;
48
49 public function __construct(
50 NamespaceInfo $nsInfo = null,
51 ILoadBalancer $loadBalancer = null,
52 UserOptionsLookup $userOptionsLookup = null
53 ) {
54 $this->nsInfo = $nsInfo ?? MediaWikiServices::getInstance()->getNamespaceInfo();
55 $this->loadBalancer = $loadBalancer;
56 $this->userOptionsLookup = $userOptionsLookup ?? MediaWikiServices::getInstance()->getUserOptionsLookup();
57 }
58
63 protected function getDefault() {
64 if ( $this->default === null ) {
65 $this->default = $this->userOptionsLookup->getDefaultOption( 'gender' );
66 }
67
68 return $this->default;
69 }
70
77 public function getGenderOf( $username, $caller = '' ) {
78 if ( $username instanceof UserIdentity ) {
79 $username = $username->getName();
80 }
81
82 $username = self::normalizeUsername( $username );
83 if ( !isset( $this->cache[$username] ) ) {
84 if ( $this->misses >= $this->missLimit &&
85 RequestContext::getMain()->getUser()->getName() !== $username
86 ) {
87 if ( $this->misses === $this->missLimit ) {
88 $this->misses++;
89 wfDebug( __METHOD__ . ": too many misses, returning default onwards" );
90 }
91
92 return $this->getDefault();
93 } else {
94 $this->misses++;
95 $this->doQuery( $username, $caller );
96 }
97 }
98
99 /* Undefined if there is a valid username which for some reason doesn't
100 * exist in the database.
101 */
102 return $this->cache[$username] ?? $this->getDefault();
103 }
104
111 public function doLinkBatch( $data, $caller = '' ) {
112 $users = [];
113 foreach ( $data as $ns => $pagenames ) {
114 if ( !$this->nsInfo->hasGenderDistinction( $ns ) ) {
115 continue;
116 }
117 foreach ( array_keys( $pagenames ) as $username ) {
118 $users[$username] = true;
119 }
120 }
121
122 $this->doQuery( array_keys( $users ), $caller );
123 }
124
132 public function doTitlesArray( $titles, $caller = '' ) {
133 $users = [];
134 foreach ( $titles as $titleObj ) {
135 if ( !$this->nsInfo->hasGenderDistinction( $titleObj->getNamespace() ) ) {
136 continue;
137 }
138 $users[] = $titleObj->getText();
139 }
140
141 $this->doQuery( $users, $caller );
142 }
143
149 public function doQuery( $users, $caller = '' ) {
150 $default = $this->getDefault();
151
152 $usersToCheck = [];
153 foreach ( (array)$users as $value ) {
154 $name = self::normalizeUsername( $value );
155 // Skip users whose gender setting we already know
156 if ( !isset( $this->cache[$name] ) ) {
157 // For existing users, this value will be overwritten by the correct value
158 $this->cache[$name] = $default;
159 // We no longer verify that only valid names are checked for, T267054
160 $usersToCheck[] = $name;
161 }
162 }
163
164 if ( count( $usersToCheck ) === 0 ) {
165 return;
166 }
167
168 // Only query database, when load balancer is provided by service wiring
169 // This maybe not happen when running as part of the installer
170 if ( $this->loadBalancer === null ) {
171 return;
172 }
173
174 $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
175 $table = [ 'user', 'user_properties' ];
176 $fields = [ 'user_name', 'up_value' ];
177 $conds = [ 'user_name' => $usersToCheck ];
178 $joins = [ 'user_properties' =>
179 [ 'LEFT JOIN', [ 'user_id = up_user', 'up_property' => 'gender' ] ] ];
180
181 $comment = __METHOD__;
182 if ( strval( $caller ) !== '' ) {
183 $comment .= "/$caller";
184 }
185 $res = $dbr->select( $table, $fields, $conds, $comment, [], $joins );
186
187 foreach ( $res as $row ) {
188 $this->cache[$row->user_name] = $row->up_value ?: $default;
189 }
190 }
191
192 private static function normalizeUsername( $username ) {
193 // Strip off subpages
194 $indexSlash = strpos( $username, '/' );
195 if ( $indexSlash !== false ) {
196 $username = substr( $username, 0, $indexSlash );
197 }
198
199 // normalize underscore/spaces
200 return strtr( $username, '_', ' ' );
201 }
202}
getUser()
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.
doLinkBatch( $data, $caller='')
Wrapper for doQuery that processes raw LinkBatch data.
getDefault()
Returns the default gender option in this wiki.
doTitlesArray( $titles, $caller='')
Wrapper for doQuery that processes a title array.
doQuery( $users, $caller='')
Preloads genders for given list of users.
Service locator for MediaWiki core services.
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.
Create and track the database connections and transactions for a given database cluster.
$cache
Definition mcc.php:33
const DB_REPLICA
Definition defines.php:26