* @param array $flags Defining the custom strings that maps to the flags
* @param array $manualLevel Limit for supported variants
*/
- public function __construct( $langobj, $maincode, $variants = [],
+ public function __construct( Language $langobj, $maincode, $variants = [],
$variantfallbacks = [], $flags = [],
$manualLevel = [] ) {
global $wgDisabledVariants;
$req = $this->validateVariant( $wgDefaultLanguageVariant );
}
+ $req = $this->validateVariant( $req );
+
// This function, unlike the other get*Variant functions, is
// not memoized (i.e. there return value is not cached) since
// new information might appear during processing after this
// is first called.
- if ( $this->validateVariant( $req ) ) {
+ if ( $req ) {
return $req;
}
return $this->mMainLanguageCode;
* @return mixed Returns the variant if it is valid, null otherwise
*/
public function validateVariant( $variant = null ) {
- if ( $variant !== null && in_array( $variant, $this->mVariants ) ) {
+ if ( $variant === null ) {
+ return null;
+ }
+ // Our internal variants are always lower-case; the variant we
+ // are validating may have mixed case.
+ $variant = LanguageCode::replaceDeprecatedCodes( strtolower( $variant ) );
+ if ( in_array( $variant, $this->mVariants ) ) {
return $variant;
}
+ // Browsers are supposed to use BCP 47 standard in the
+ // Accept-Language header, but not all of our internal
+ // mediawiki variant codes are BCP 47. Map BCP 47 code
+ // to our internal code.
+ foreach ( $this->mVariants as $v ) {
+ // Case-insensitive match (BCP 47 is mixed case)
+ if ( strtolower( LanguageCode::bcp47( $v ) ) === $variant ) {
+ return $v;
+ }
+ }
return null;
}
return $this->mHeaderVariant;
}
- // see if some supported language variant is set in the
+ // See if some supported language variant is set in the
// HTTP header.
$languages = array_keys( $wgRequest->getAcceptLang() );
if ( empty( $languages ) ) {
$convTable = $convRule->getConvTable();
$action = $convRule->getRulesAction();
foreach ( $convTable as $variant => $pair ) {
- if ( !$this->validateVariant( $variant ) ) {
+ $v = $this->validateVariant( $variant );
+ if ( !$v ) {
continue;
}
if ( $action == 'add' ) {
// More efficient than array_merge(), about 2.5 times.
foreach ( $pair as $from => $to ) {
- $this->mTables[$variant]->setPair( $from, $to );
+ $this->mTables[$v]->setPair( $from, $to );
}
} elseif ( $action == 'remove' ) {
- $this->mTables[$variant]->removeArray( $pair );
+ $this->mTables[$v]->removeArray( $pair );
}
}
}
* -{flags|code1:text1;code2:text2;...}- or
* -{text}- in which case no conversion should take place for text
*
- * @param string $text Text to be converted
- * @return string Converted text
+ * @warning Glossary state is maintained between calls. Never feed this
+ * method input that hasn't properly been escaped as it may result in
+ * an XSS in subsequent calls, even if those subsequent calls properly
+ * escape things.
+ * @param string $text Text to be converted, already html escaped.
+ * @return string Converted text (html)
*/
public function convert( $text ) {
$variant = $this->getPreferredVariant();
/**
* Same as convert() except a extra parameter to custom variant.
*
- * @param string $text Text to be converted
+ * @param string $text Text to be converted, already html escaped
+ * @param-taint $text exec_html
* @param string $variant The target variant code
* @return string Converted text
+ * @return-taint escaped
*/
public function convertTo( $text, $variant ) {
global $wgDisableLangConversion;
$warningDone = true;
}
$startPos += 2;
- continue;
+ break;
}
// Recursively parse another rule
$inner .= $this->recursiveConvertRule( $text, $variant, $startPos, $depth + 1 );