Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4111130
LanguageLibrary.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
LanguageLibrary.php
View Options
<?php
namespace
MediaWiki\Extension\Scribunto\Engines\LuaCommon
;
use
DateTime
;
use
DateTimeZone
;
use
Exception
;
use
MediaWiki\Language\Language
;
use
MediaWiki\Language\LanguageCode
;
use
MediaWiki\Languages\LanguageNameUtils
;
use
MediaWiki\MainConfigNames
;
use
MediaWiki\MediaWikiServices
;
use
MediaWiki\Title\Title
;
use
MediaWiki\User\User
;
use
MediaWiki\Utils\MWTimestamp
;
use
Wikimedia\RequestTimeout\TimeoutException
;
class
LanguageLibrary
extends
LibraryBase
{
/** @var Language[] */
public
$langCache
=
[];
/** @var array[] */
public
$timeCache
=
[];
/** @var int */
public
$maxLangCacheSize
;
public
function
register
()
{
// Pre-populate the language cache
$contLang
=
MediaWikiServices
::
getInstance
()->
getContentLanguage
();
$this
->
langCache
[
$contLang
->
getCode
()]
=
$contLang
;
$this
->
maxLangCacheSize
=
$this
->
getEngine
()->
getOption
(
'maxLangCacheSize'
);
$statics
=
[
'getContLangCode'
,
'isSupportedLanguage'
,
'isKnownLanguageTag'
,
'isValidCode'
,
'isValidBuiltInCode'
,
'fetchLanguageName'
,
'fetchLanguageNames'
,
'getFallbacksFor'
,
'toBcp47Code'
,
];
$methods
=
[
'lcfirst'
,
'ucfirst'
,
'lc'
,
'uc'
,
'caseFold'
,
'formatNum'
,
'formatDate'
,
'formatDuration'
,
'getDurationIntervals'
,
'parseFormattedNumber'
,
'convertPlural'
,
'convertGrammar'
,
'gender'
,
'isRTL'
,
];
$lib
=
[];
foreach
(
$statics
as
$name
)
{
$lib
[
$name
]
=
[
$this
,
$name
];
}
foreach
(
$methods
as
$name
)
{
$lib
[
$name
]
=
function
()
use
(
$name
)
{
$args
=
func_get_args
();
return
$this
->
languageMethod
(
$name
,
$args
);
};
}
return
$this
->
getEngine
()->
registerInterface
(
'mw.language.lua'
,
$lib
);
}
/**
* Handler for getContLangCode
* @internal
* @return string[]
*/
public
function
getContLangCode
()
{
return
[
MediaWikiServices
::
getInstance
()->
getContentLanguage
()->
getCode
()
];
}
/**
* Handler for isSupportedLanguage
* @internal
* @param string $code
* @return bool[]
*/
public
function
isSupportedLanguage
(
$code
)
{
$this
->
checkType
(
'isSupportedLanguage'
,
1
,
$code
,
'string'
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()->
isSupportedLanguage
(
$code
)
];
}
/**
* Handler for isKnownLanguageTag
* @internal
* @param string $code
* @return bool[]
*/
public
function
isKnownLanguageTag
(
$code
)
{
$this
->
checkType
(
'isKnownLanguageTag'
,
1
,
$code
,
'string'
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()->
isKnownLanguageTag
(
$code
)
];
}
/**
* Handler for isValidCode
* @internal
* @param string $code
* @return bool[]
*/
public
function
isValidCode
(
$code
)
{
$this
->
checkType
(
'isValidCode'
,
1
,
$code
,
'string'
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()->
isValidCode
(
$code
)
];
}
/**
* Handler for isValidBuiltInCode
* @internal
* @param string $code
* @return bool[]
*/
public
function
isValidBuiltInCode
(
$code
)
{
$this
->
checkType
(
'isValidBuiltInCode'
,
1
,
$code
,
'string'
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()->
isValidBuiltInCode
(
$code
)
];
}
/**
* Handler for fetchLanguageName
* @internal
* @param string $code
* @param null|string $inLanguage
* @return string[]
*/
public
function
fetchLanguageName
(
$code
,
$inLanguage
)
{
$this
->
checkType
(
'fetchLanguageName'
,
1
,
$code
,
'string'
);
$this
->
checkTypeOptional
(
'fetchLanguageName'
,
2
,
$inLanguage
,
'string'
,
LanguageNameUtils
::
AUTONYMS
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()
->
getLanguageName
(
$code
,
$inLanguage
)
];
}
/**
* Handler for fetchLanguageNames
* @internal
* @param null|string $inLanguage
* @param null|string $include
* @return string[][]
*/
public
function
fetchLanguageNames
(
$inLanguage
,
$include
)
{
$this
->
checkTypeOptional
(
'fetchLanguageNames'
,
1
,
$inLanguage
,
'string'
,
LanguageNameUtils
::
AUTONYMS
);
$this
->
checkTypeOptional
(
'fetchLanguageNames'
,
2
,
$include
,
'string'
,
LanguageNameUtils
::
DEFINED
);
return
[
MediaWikiServices
::
getInstance
()->
getLanguageNameUtils
()
->
getLanguageNames
(
$inLanguage
,
$include
)
];
}
/**
* Handler for fetchLanguageNames
* @internal
* @param string $code
* @return string[][]
*/
public
function
getFallbacksFor
(
$code
)
{
$this
->
checkType
(
'getFallbacksFor'
,
1
,
$code
,
'string'
);
$ret
=
MediaWikiServices
::
getInstance
()->
getLanguageFallback
()->
getAll
(
$code
);
// Make 1-based
if
(
count
(
$ret
)
)
{
$ret
=
array_combine
(
range
(
1
,
count
(
$ret
)
),
$ret
);
}
return
[
$ret
];
}
/**
* Handler for toBcp47Code
* @internal
* @param string $code a MediaWiki-internal code
* @return string[] a BCP-47 language tag
*/
public
function
toBcp47Code
(
$code
)
{
$this
->
checkType
(
'toBcp47Code'
,
1
,
$code
,
'string'
);
$ret
=
LanguageCode
::
bcp47
(
$code
);
return
[
$ret
];
}
/**
* Language object method handler
* @internal
* @param string $name
* @param array $args
* @return array
* @throws LuaError
*/
public
function
languageMethod
(
string
$name
,
array
$args
):
array
{
if
(
!
is_string
(
$args
[
0
]
??
null
)
)
{
throw
new
LuaError
(
"invalid code property of language object when calling $name"
);
}
$code
=
array_shift
(
$args
);
if
(
!
isset
(
$this
->
langCache
[
$code
]
)
)
{
if
(
count
(
$this
->
langCache
)
>
$this
->
maxLangCacheSize
)
{
throw
new
LuaError
(
'too many language codes requested'
);
}
$services
=
MediaWikiServices
::
getInstance
();
if
(
$services
->
getLanguageNameUtils
()->
isValidCode
(
$code
)
)
{
$this
->
langCache
[
$code
]
=
$services
->
getLanguageFactory
()->
getLanguage
(
$code
);
}
else
{
throw
new
LuaError
(
"language code '$code' is invalid"
);
}
}
$lang
=
$this
->
langCache
[
$code
];
switch
(
$name
)
{
// Zero arguments
case
'isRTL'
:
return
[
$lang
->
$name
()
];
// One string argument passed straight through
case
'lcfirst'
:
case
'ucfirst'
:
case
'lc'
:
case
'uc'
:
case
'caseFold'
:
$this
->
checkType
(
$name
,
1
,
$args
[
0
],
'string'
);
return
[
$lang
->
$name
(
$args
[
0
]
)
];
case
'parseFormattedNumber'
:
if
(
is_numeric
(
$args
[
0
]
)
)
{
$args
[
0
]
=
strval
(
$args
[
0
]
);
}
if
(
$this
->
getLuaType
(
$args
[
0
]
)
!==
'string'
)
{
// Be like tonumber(), return nil instead of erroring out
return
[
null
];
}
return
[
$lang
->
$name
(
$args
[
0
]
)
];
// Custom handling
default
:
return
$this
->
$name
(
$lang
,
$args
);
}
}
/**
* convertPlural handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
convertPlural
(
$lang
,
$args
)
{
$number
=
array_shift
(
$args
);
$this
->
checkType
(
'convertPlural'
,
1
,
$number
,
'number'
);
if
(
is_array
(
$args
[
0
]
)
)
{
$args
=
$args
[
0
];
}
$forms
=
array_values
(
array_map
(
'strval'
,
$args
)
);
return
[
$lang
->
convertPlural
(
$number
,
$forms
)
];
}
/**
* convertGrammar handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
convertGrammar
(
$lang
,
$args
)
{
$this
->
checkType
(
'convertGrammar'
,
1
,
$args
[
0
],
'string'
);
$this
->
checkType
(
'convertGrammar'
,
2
,
$args
[
1
],
'string'
);
return
[
$lang
->
convertGrammar
(
$args
[
0
],
$args
[
1
]
)
];
}
/**
* gender handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
gender
(
$lang
,
$args
)
{
$this
->
checkType
(
'gender'
,
1
,
$args
[
0
],
'string'
);
$username
=
trim
(
array_shift
(
$args
)
);
if
(
is_array
(
$args
[
0
]
)
)
{
$args
=
$args
[
0
];
}
$forms
=
array_values
(
array_map
(
'strval'
,
$args
)
);
// Shortcuts
if
(
count
(
$forms
)
===
0
)
{
return
[
''
];
}
elseif
(
count
(
$forms
)
===
1
)
{
return
[
$forms
[
0
]
];
}
if
(
$username
===
'male'
||
$username
===
'female'
)
{
$gender
=
$username
;
}
else
{
$userOptionsLookup
=
MediaWikiServices
::
getInstance
()->
getUserOptionsLookup
();
// default
$gender
=
$userOptionsLookup
->
getDefaultOption
(
'gender'
);
// Check for "User:" prefix
$title
=
Title
::
newFromText
(
$username
);
if
(
$title
&&
$title
->
getNamespace
()
===
NS_USER
)
{
$username
=
$title
->
getText
();
}
// check parameter, or use the ParserOptions if in interface message
$user
=
User
::
newFromName
(
$username
);
if
(
$user
)
{
$genderCache
=
MediaWikiServices
::
getInstance
()->
getGenderCache
();
$gender
=
$genderCache
->
getGenderOf
(
$user
,
__METHOD__
);
}
elseif
(
$username
===
''
)
{
$parserOptions
=
$this
->
getParserOptions
();
if
(
$parserOptions
->
getInterfaceMessage
()
)
{
$genderCache
=
MediaWikiServices
::
getInstance
()->
getGenderCache
();
$gender
=
$genderCache
->
getGenderOf
(
$parserOptions
->
getUserIdentity
(),
__METHOD__
);
}
}
}
return
[
$lang
->
gender
(
$gender
,
$forms
)
];
}
/**
* formatNum handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
formatNum
(
$lang
,
$args
)
{
$num
=
$args
[
0
];
$this
->
checkType
(
'formatNum'
,
1
,
$num
,
'number'
);
if
(
is_infinite
(
$num
)
)
{
throw
new
LuaError
(
"bad argument #1 to 'formatNum' (infinite)"
);
}
if
(
is_nan
(
$num
)
)
{
throw
new
LuaError
(
"bad argument #1 to 'formatNum' (NaN)"
);
}
$noCommafy
=
false
;
if
(
isset
(
$args
[
1
]
)
)
{
$this
->
checkType
(
'formatNum'
,
2
,
$args
[
1
],
'table'
);
$options
=
$args
[
1
];
$noCommafy
=
!
empty
(
$options
[
'noCommafy'
]
);
}
if
(
$noCommafy
)
{
return
[
$lang
->
formatNumNoSeparators
(
$num
)
];
}
else
{
return
[
$lang
->
formatNum
(
$num
)
];
}
}
/**
* formatDate handler
* @internal
* @param Language $lang
* @param array $args
* @return array
* @throws LuaError
*/
public
function
formatDate
(
$lang
,
$args
)
{
$this
->
checkType
(
'formatDate'
,
1
,
$args
[
0
],
'string'
);
$this
->
checkTypeOptional
(
'formatDate'
,
2
,
$args
[
1
],
'string'
,
''
);
$this
->
checkTypeOptional
(
'formatDate'
,
3
,
$args
[
2
],
'boolean'
,
false
);
[
$format
,
$date
,
$local
]
=
$args
;
$langcode
=
$lang
->
getCode
();
if
(
$date
===
''
)
{
$cacheKey
=
$this
->
getParserOptions
()->
getTimestamp
();
$timestamp
=
new
MWTimestamp
(
$cacheKey
);
$date
=
$timestamp
->
getTimestamp
(
TS_ISO_8601
);
$useTTL
=
true
;
}
else
{
# Correct for DateTime interpreting 'XXXX' as XX:XX o'clock
if
(
preg_match
(
'/^[0-9]{4}$/'
,
$date
)
)
{
$date
=
'00:00 '
.
$date
;
}
$cacheKey
=
$date
;
$useTTL
=
false
;
}
if
(
isset
(
$this
->
timeCache
[
$format
][
$cacheKey
][
$langcode
][
$local
]
)
)
{
$ttl
=
$this
->
timeCache
[
$format
][
$cacheKey
][
$langcode
][
$local
][
1
];
if
(
$useTTL
&&
$ttl
!==
null
)
{
$this
->
getEngine
()->
setTTL
(
$ttl
);
}
return
[
$this
->
timeCache
[
$format
][
$cacheKey
][
$langcode
][
$local
][
0
]
];
}
# Default input timezone is UTC.
try
{
$utc
=
new
DateTimeZone
(
'UTC'
);
$dateObject
=
new
DateTime
(
$date
,
$utc
);
}
catch
(
TimeoutException
$ex
)
{
// Unfortunately DateTime throws a generic Exception, but we can't
// ignore an exception generated by the RequestTimeout library.
throw
$ex
;
}
catch
(
Exception
$ex
)
{
throw
new
LuaError
(
"bad argument #2 to 'formatDate': invalid timestamp '$date'"
);
}
# Set output timezone.
if
(
$local
)
{
$localtimezone
=
MediaWikiServices
::
getInstance
()->
getMainConfig
()->
get
(
MainConfigNames
::
Localtimezone
);
if
(
isset
(
$localtimezone
)
)
{
$tz
=
new
DateTimeZone
(
$localtimezone
);
}
else
{
$tz
=
new
DateTimeZone
(
date_default_timezone_get
()
);
}
}
else
{
$tz
=
$utc
;
}
$dateObject
->
setTimezone
(
$tz
);
# Generate timestamp
$ts
=
$dateObject
->
format
(
'YmdHis'
);
if
(
$ts
<
0
)
{
throw
new
LuaError
(
"mw.language:formatDate() only supports years from 0"
);
}
elseif
(
$ts
>=
100000000000000
)
{
throw
new
LuaError
(
"mw.language:formatDate() only supports years up to 9999"
);
}
$ttl
=
null
;
$ret
=
$lang
->
sprintfDate
(
$format
,
$ts
,
$tz
,
$ttl
);
$this
->
timeCache
[
$format
][
$cacheKey
][
$langcode
][
$local
]
=
[
$ret
,
$ttl
];
if
(
$useTTL
&&
$ttl
!==
null
)
{
$this
->
getEngine
()->
setTTL
(
$ttl
);
}
return
[
$ret
];
}
/**
* formatDuration handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
formatDuration
(
$lang
,
$args
)
{
$this
->
checkType
(
'formatDuration'
,
1
,
$args
[
0
],
'number'
);
$this
->
checkTypeOptional
(
'formatDuration'
,
2
,
$args
[
1
],
'table'
,
[]
);
[
$seconds
,
$chosenIntervals
]
=
$args
;
$chosenIntervals
=
array_values
(
$chosenIntervals
);
$ret
=
$lang
->
formatDuration
(
$seconds
,
$chosenIntervals
);
return
[
$ret
];
}
/**
* getDurationIntervals handler
* @internal
* @param Language $lang
* @param array $args
* @return array
*/
public
function
getDurationIntervals
(
$lang
,
$args
)
{
$this
->
checkType
(
'getDurationIntervals'
,
1
,
$args
[
0
],
'number'
);
$this
->
checkTypeOptional
(
'getDurationIntervals'
,
2
,
$args
[
1
],
'table'
,
[]
);
[
$seconds
,
$chosenIntervals
]
=
$args
;
$chosenIntervals
=
array_values
(
$chosenIntervals
);
$ret
=
$lang
->
getDurationIntervals
(
$seconds
,
$chosenIntervals
);
return
[
$ret
];
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Aug 18, 22:10 (1 d, 20 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a5/c4/0eaa3ee41f4b2ab1c0ed37be666d
Default Alt Text
LanguageLibrary.php (12 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment