MediaWiki master
GenderCache.php
Go to the documentation of this file.
1<?php
22namespace MediaWiki\Cache;
23
29
42 protected $cache = [];
44 protected $default = null;
46 protected $misses = 0;
51 protected $missLimit = 1000;
52
53 private NamespaceInfo $nsInfo;
54 private UserOptionsLookup $userOptionsLookup;
55
56 public function __construct(
57 NamespaceInfo $nsInfo,
58 UserOptionsLookup $userOptionsLookup
59 ) {
60 $this->nsInfo = $nsInfo;
61 $this->userOptionsLookup = $userOptionsLookup;
62 }
63
69 protected function getDefault() {
70 $this->default ??= $this->userOptionsLookup->getDefaultOption( 'gender' );
71 return $this->default;
72 }
73
81 public function getGenderOf( $username, $caller = '' ) {
82 if ( $username instanceof UserIdentity ) {
83 $username = $username->getName();
84 }
85
86 $username = self::normalizeUsername( $username );
87 if ( !isset( $this->cache[$username] ) ) {
88 if ( $this->misses < $this->missLimit ||
89 RequestContext::getMain()->getUser()->getName() === $username
90 ) {
91 $this->misses++;
92 $this->doQuery( $username, $caller );
93 }
94 if ( $this->misses === $this->missLimit ) {
95 // Log only once and don't bother incrementing beyond limit+1
96 $this->misses++;
97 wfDebug( __METHOD__ . ': too many misses, returning default onwards' );
98 }
99 }
100
101 return $this->cache[$username] ?? $this->getDefault();
102 }
103
110 public function doLinkBatch( array $data, $caller = '' ) {
111 $users = [];
112 foreach ( $data as $ns => $pagenames ) {
113 if ( $this->nsInfo->hasGenderDistinction( $ns ) ) {
114 $users += $pagenames;
115 }
116 }
117 $this->doQuery( array_keys( $users ), $caller );
118 }
119
127 public function doTitlesArray( $titles, $caller = '' ) {
128 $users = [];
129 foreach ( $titles as $titleObj ) {
130 if ( $this->nsInfo->hasGenderDistinction( $titleObj->getNamespace() ) ) {
131 $users[] = $titleObj->getText();
132 }
133 }
134 $this->doQuery( $users, $caller );
135 }
136
143 public function doQuery( $users, $caller = '' ) {
144 $usersToFetch = [];
145 foreach ( (array)$users as $userName ) {
146 $userName = self::normalizeUsername( $userName );
147 if ( !isset( $this->cache[$userName] ) ) {
148 $usersToFetch[] = $userName;
149 }
150 }
151 if ( !$usersToFetch ) {
152 return;
153 }
154
155 $genders = $this->userOptionsLookup->getOptionBatchForUserNames( $usersToFetch, 'gender' );
156 foreach ( $genders as $userName => $gender ) {
157 $this->cache[$userName] = $gender;
158 }
159 }
160
161 private static function normalizeUsername( string $username ): string {
162 // Strip off subpages
163 $indexSlash = strpos( $username, '/' );
164 if ( $indexSlash !== false ) {
165 $username = substr( $username, 0, $indexSlash );
166 }
167
168 // normalize underscore/spaces
169 return strtr( $username, '_', ' ' );
170 }
171}
172
174class_alias( GenderCache::class, 'GenderCache' );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Look up "gender" user preference.
__construct(NamespaceInfo $nsInfo, UserOptionsLookup $userOptionsLookup)
doQuery( $users, $caller='')
Preload gender option for multiple user names.
getDefault()
Get the default gender option on this wiki.
getGenderOf( $username, $caller='')
Get the gender option for given username.
doTitlesArray( $titles, $caller='')
Wrapper for doQuery that processes a title array.
doLinkBatch(array $data, $caller='')
Wrapper for doQuery that processes raw LinkBatch data.
Group all the pieces relevant to the context of a request into one instance.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Provides access to user options.
Represents the target of a wiki link.
Interface for objects representing user identity.