mediawiki-extensions-Discus.../includes/LanguageData.php
Bartosz Dziewoński e72f58ca78 Remove some redundant PHPDoc comments
Inspired by this Wikitech-l discussion:
https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/NWXPNHRNLEVXHSWX33H473OAWQP6CDOA/

To keep this simple for now, I am only removing redundant PHPDoc
comments on constructors, and only when all the documentation for
parameters completely duplicates type hints.

More could be done, but that can happen later when we have better
tooling. Redundant comments on constructors that take a dozen services
are by far the most annoying for me and I want them gone now.

Change-Id: I86cbf7d6e48035cfa06f780c8fb1b02e68709a0c
2022-11-29 18:47:18 +00:00

229 lines
7.1 KiB
PHP

<?php
/**
* Generates language-specific data used by DiscussionTools.
*
* @file
* @ingroup Extensions
* @license MIT
*/
namespace MediaWiki\Extension\DiscussionTools;
use Config;
use DateTimeZone;
use ILanguageConverter;
use Language;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\SpecialPage\SpecialPageFactory;
class LanguageData {
private Config $config;
private Language $language;
private LanguageConverterFactory $languageConverterFactory;
private SpecialPageFactory $specialPageFactory;
public function __construct(
Config $config,
Language $language,
LanguageConverterFactory $languageConverterFactory,
SpecialPageFactory $specialPageFactory
) {
$this->config = $config;
$this->language = $language;
$this->languageConverterFactory = $languageConverterFactory;
$this->specialPageFactory = $specialPageFactory;
}
/**
* Compute data we need to parse discussion threads on pages.
*
* @return array
*/
public function getLocalData(): array {
$config = $this->config;
$lang = $this->language;
$langConv = $this->languageConverterFactory->getLanguageConverter( $lang );
$data = [];
$data['dateFormat'] = [];
$dateFormat = $lang->getDateFormatString( 'both', $lang->dateFormat( false ) );
foreach ( $langConv->getVariants() as $variant ) {
$convDateFormat = $this->convertDateFormat( $dateFormat, $langConv, $variant );
$data['dateFormat'][$variant] = $convDateFormat;
}
$data['digits'] = [];
foreach ( $langConv->getVariants() as $variant ) {
$data['digits'][$variant] = [];
foreach ( str_split( '0123456789' ) as $digit ) {
if ( $config->get( 'TranslateNumerals' ) ) {
$localDigit = $lang->formatNumNoSeparators( $digit );
} else {
$localDigit = $digit;
}
$convLocalDigit = $langConv->translate( $localDigit, $variant );
$data['digits'][$variant][] = $convLocalDigit;
}
}
// ApiQuerySiteinfo
$data['localTimezone'] = $config->get( 'Localtimezone' );
$data['specialContributionsName'] = $this->specialPageFactory
->getLocalNameFor( 'Contributions' );
$data['specialNewSectionName'] = $this->specialPageFactory
->getLocalNameFor( 'NewSection' );
$localTimezone = $config->get( 'Localtimezone' );
// Return all timezone abbreviations for the local timezone (there will often be two, for
// non-DST and DST timestamps, and sometimes more due to historical data, but that's okay).
// Avoid DateTimeZone::listAbbreviations(), it returns some half-baked list that is different
// from the timezone data used by everything else in PHP.
$timezoneTransitions = ( new DateTimeZone( $localTimezone ) )->getTransitions();
if ( !is_array( $timezoneTransitions ) ) {
// Handle (arguably invalid) config where $wgLocaltimezone is an abbreviation like "CST"
// instead of a real IANA timezone name like "America/Chicago". (T312310)
// "DateTimeZone objects wrapping type 1 (UTC offsets) and type 2 (abbreviations) do not
// contain any transitions, and calling this method on them will return false."
// https://www.php.net/manual/en/datetimezone.gettransitions.php
$timezoneAbbrs = [ $localTimezone ];
} else {
$timezoneAbbrs = array_values( array_unique(
array_map( static function ( $transition ) {
return $transition['abbr'];
}, $timezoneTransitions )
) );
}
$data['timezones'] = [];
foreach ( $langConv->getVariants() as $variant ) {
$data['timezones'][$variant] = array_combine(
array_map( static function ( string $tzMsg ) use ( $lang, $langConv, $variant ) {
// MWTimestamp::getTimezoneMessage()
// Parser::pstPass2()
// Messages used here: 'timezone-utc' and so on
$key = 'timezone-' . strtolower( trim( $tzMsg ) );
$msg = wfMessage( $key )->inLanguage( $lang );
// TODO: This probably causes a similar issue to https://phabricator.wikimedia.org/T221294,
// but we *must* check the message existence in the database, because the messages are not
// actually defined by MediaWiki core for any timezone other than UTC...
if ( $msg->exists() ) {
$text = $msg->text();
} else {
$text = strtoupper( $tzMsg );
}
$convText = $langConv->translate( $text, $variant );
return $convText;
}, $timezoneAbbrs ),
array_map( 'strtoupper', $timezoneAbbrs )
);
}
// Messages in content language
$messagesKeys = array_merge(
Language::WEEKDAY_MESSAGES,
Language::WEEKDAY_ABBREVIATED_MESSAGES,
Language::MONTH_MESSAGES,
Language::MONTH_GENITIVE_MESSAGES,
Language::MONTH_ABBREVIATED_MESSAGES
);
$data['contLangMessages'] = [];
foreach ( $langConv->getVariants() as $variant ) {
$data['contLangMessages'][$variant] = array_combine(
$messagesKeys,
array_map( static function ( $key ) use ( $lang, $langConv, $variant ) {
$text = wfMessage( $key )->inLanguage( $lang )->text();
return $langConv->translate( $text, $variant );
}, $messagesKeys )
);
}
return $data;
}
/**
* Convert a date format string to a different language variant, leaving all special characters
* unchanged and applying language conversion to the plain text fragments.
*
* @param string $format
* @param ILanguageConverter $langConv
* @param string $variant
* @return string
*/
private function convertDateFormat(
string $format,
ILanguageConverter $langConv,
string $variant
): string {
$formatLength = strlen( $format );
$s = '';
// The supported codes must match CommentParser::getTimestampRegexp()
for ( $p = 0; $p < $formatLength; $p++ ) {
$num = false;
$code = $format[ $p ];
if ( $code === 'x' && $p < $formatLength - 1 ) {
$code .= $format[++$p];
}
if ( $code === 'xk' && $p < $formatLength - 1 ) {
$code .= $format[++$p];
}
// LAZY SHORTCUTS that might cause bugs:
// * We assume that result of $langConv->translate() doesn't produce any special codes/characters
// * We assume that calling $langConv->translate() separately for each character is correct
switch ( $code ) {
case 'xx':
case 'xg':
case 'd':
case 'D':
case 'j':
case 'l':
case 'F':
case 'M':
case 'n':
case 'Y':
case 'xkY':
case 'G':
case 'H':
case 'i':
// Special code - pass through unchanged
$s .= $code;
break;
case '\\':
// Plain text (backslash escaping) - convert to language variant
if ( $p < $formatLength - 1 ) {
$s .= '\\' . $langConv->translate( $format[++$p], $variant );
} else {
$s .= $code;
}
break;
case '"':
// Plain text (quoted literal) - convert to language variant
if ( $p < $formatLength - 1 ) {
$endQuote = strpos( $format, '"', $p + 1 );
if ( $endQuote === false ) {
// No terminating quote, assume literal "
$s .= $code;
} else {
$s .= '"' .
$langConv->translate( substr( $format, $p + 1, $endQuote - $p - 1 ), $variant ) .
'"';
$p = $endQuote;
}
} else {
// Quote at end of string, assume literal "
$s .= $code;
}
break;
default:
// Plain text - convert to language variant
$s .= $langConv->translate( $format[$p], $variant );
}
}
return $s;
}
}