Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4073185
GenderCache.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
GenderCache.php
View Options
<?php
/**
* @license GPL-2.0-or-later
* @file
* @author Niklas Laxström
*/
namespace
MediaWiki\Cache
;
use
MediaWiki\Context\RequestContext
;
use
MediaWiki\Linker\LinkTarget
;
use
MediaWiki\Title\NamespaceInfo
;
use
MediaWiki\User\Options\UserOptionsLookup
;
use
MediaWiki\User\UserIdentity
;
use
Wikimedia\Rdbms\IResultWrapper
;
/**
* Look up "gender" user preference.
*
* This primarily used in MediaWiki\Title\TitleFormatter for title formatting
* of pages in gendered namespace aliases, and in CoreParserFunctions for the
* `{{gender:}}` parser function.
*
* @since 1.18
* @ingroup Cache
*/
class
GenderCache
{
/** @var string[] */
protected
$cache
=
[];
/** @var string|null */
protected
$default
=
null
;
/** @var int */
protected
$misses
=
0
;
/**
* @internal Exposed for MediaWiki core unit tests.
* @var int
*/
protected
$missLimit
=
1000
;
private
NamespaceInfo
$nsInfo
;
private
UserOptionsLookup
$userOptionsLookup
;
public
function
__construct
(
NamespaceInfo
$nsInfo
,
UserOptionsLookup
$userOptionsLookup
)
{
$this
->
nsInfo
=
$nsInfo
;
$this
->
userOptionsLookup
=
$userOptionsLookup
;
}
/**
* Get the default gender option on this wiki.
*
* @return string
*/
protected
function
getDefault
()
{
$this
->
default
??=
$this
->
userOptionsLookup
->
getDefaultOption
(
'gender'
);
return
$this
->
default
;
}
/**
* Get the gender option for given username.
*
* @param string|UserIdentity $username
* @param string|null $caller Unused since 1.44
* @return string
*/
public
function
getGenderOf
(
$username
,
$caller
=
''
)
{
if
(
$username
instanceof
UserIdentity
)
{
$username
=
$username
->
getName
();
}
$username
=
self
::
normalizeUsername
(
$username
);
if
(
!
isset
(
$this
->
cache
[
$username
]
)
)
{
if
(
$this
->
misses
<
$this
->
missLimit
||
RequestContext
::
getMain
()->
getUser
()->
getName
()
===
$username
)
{
$this
->
misses
++;
$this
->
doQuery
(
$username
);
}
if
(
$this
->
misses
===
$this
->
missLimit
)
{
// Log only once and don't bother incrementing beyond limit+1
$this
->
misses
++;
wfDebug
(
__METHOD__
.
': too many misses, returning default onwards'
);
}
}
return
$this
->
cache
[
$username
]
??
$this
->
getDefault
();
}
/**
* Wrapper for doQuery that processes raw LinkBatch data.
*
* @param array<int,array<string,mixed>> $data
* @param string|null $caller Unused since 1.44
*/
public
function
doLinkBatch
(
array
$data
,
$caller
=
''
)
{
$users
=
[];
foreach
(
$data
as
$ns
=>
$pagenames
)
{
if
(
$this
->
nsInfo
->
hasGenderDistinction
(
$ns
)
)
{
$users
+=
$pagenames
;
}
}
$this
->
doQuery
(
array_keys
(
$users
)
);
}
/**
* Wrapper for doQuery that processes a title array.
*
* @since 1.20
* @param LinkTarget[] $titles
* @param string|null $caller Unused since 1.44
*/
public
function
doTitlesArray
(
$titles
,
$caller
=
''
)
{
$users
=
[];
foreach
(
$titles
as
$titleObj
)
{
if
(
$this
->
nsInfo
->
hasGenderDistinction
(
$titleObj
->
getNamespace
()
)
)
{
$users
[]
=
$titleObj
->
getText
();
}
}
$this
->
doQuery
(
$users
);
}
/**
* Process a set of rows from the page table
*
* @since 1.45
* @param iterable<\stdClass>|IResultWrapper $rows
*/
public
function
doPageRows
(
$rows
)
{
$users
=
[];
foreach
(
$rows
as
$row
)
{
if
(
$this
->
nsInfo
->
hasGenderDistinction
(
(
int
)
$row
->
page_namespace
)
)
{
$users
[]
=
$row
->
page_title
;
}
}
$this
->
doQuery
(
$users
);
}
/**
* Preload gender option for multiple user names.
*
* @param string[]|string $users Usernames
* @param string|null $caller Unused since 1.44
*/
public
function
doQuery
(
$users
,
$caller
=
''
)
{
$usersToFetch
=
[];
foreach
(
(
array
)
$users
as
$userName
)
{
$userName
=
self
::
normalizeUsername
(
$userName
);
if
(
!
isset
(
$this
->
cache
[
$userName
]
)
)
{
$usersToFetch
[]
=
$userName
;
}
}
if
(
!
$usersToFetch
)
{
return
;
}
// Limit batch size to 1000 since the usernames need to be put into an
// IN() expression in SQL. Could be done closer to the backend, but
// there are multiple backends.
foreach
(
array_chunk
(
array_unique
(
$usersToFetch
),
1000
)
as
$batch
)
{
$genders
=
$this
->
userOptionsLookup
->
getOptionBatchForUserNames
(
$batch
,
'gender'
);
foreach
(
$genders
as
$userName
=>
$gender
)
{
$this
->
cache
[
$userName
]
=
$gender
;
}
}
}
private
static
function
normalizeUsername
(
string
$username
):
string
{
// Strip off subpages
$indexSlash
=
strpos
(
$username
,
'/'
);
if
(
$indexSlash
!==
false
)
{
$username
=
substr
(
$username
,
0
,
$indexSlash
);
}
// normalize underscore/spaces
return
strtr
(
$username
,
'_'
,
' '
);
}
}
/** @deprecated class alias since 1.42 */
class_alias
(
GenderCache
::
class
,
'GenderCache'
);
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 17 2026, 10:09 (11 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
ee/d5/919d3e8b3e43754c42745c7d4d22
Default Alt Text
GenderCache.php (4 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment