wiki.techinc.nl/includes/parser/Parsoid/LanguageVariantConverter.php

330 lines
12 KiB
PHP
Raw Normal View History

<?php
namespace MediaWiki\Parser\Parsoid;
use LanguageCode;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Languages\LanguageFactory;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Parser\Parsoid\Config\PageConfigFactory;
use MediaWiki\Rest\HttpException;
use MediaWiki\Rest\LocalizedHttpException;
use MediaWiki\Revision\RevisionAccessException;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleFactory;
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
use Wikimedia\Bcp47Code\Bcp47Code;
use Wikimedia\Bcp47Code\Bcp47CodeValue;
use Wikimedia\Message\MessageValue;
use Wikimedia\Parsoid\Config\PageConfig;
use Wikimedia\Parsoid\Config\SiteConfig;
use Wikimedia\Parsoid\Core\PageBundle;
use Wikimedia\Parsoid\DOM\Element;
use Wikimedia\Parsoid\Parsoid;
use Wikimedia\Parsoid\Utils\DOMCompat;
use Wikimedia\Parsoid\Utils\DOMUtils;
/**
* @since 1.40
* @unstable should be marked stable before 1.40 release
*/
class LanguageVariantConverter {
private PageConfigFactory $pageConfigFactory;
private ?PageConfig $pageConfig = null;
private PageIdentity $pageIdentity;
private Title $pageTitle;
private Parsoid $parsoid;
private SiteConfig $siteConfig;
private LanguageConverterFactory $languageConverterFactory;
private LanguageFactory $languageFactory;
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
/**
* Page language override from the Content-Language header.
*/
private ?Bcp47Code $pageLanguageOverride = null;
private bool $isFallbackLanguageConverterEnabled = true;
public function __construct(
PageIdentity $pageIdentity,
PageConfigFactory $pageConfigFactory,
Parsoid $parsoid,
SiteConfig $siteConfig,
TitleFactory $titleFactory,
LanguageConverterFactory $languageConverterFactory,
LanguageFactory $languageFactory
) {
$this->pageConfigFactory = $pageConfigFactory;
$this->pageIdentity = $pageIdentity;
$this->parsoid = $parsoid;
$this->siteConfig = $siteConfig;
$this->pageTitle = $titleFactory->newFromPageIdentity( $this->pageIdentity );
$this->languageConverterFactory = $languageConverterFactory;
$this->languageFactory = $languageFactory;
}
/**
* Set the PageConfig object to be used during language variant conversion.
* If not provided, the object will be created.
*
* @param PageConfig $pageConfig
* @return void
*/
public function setPageConfig( PageConfig $pageConfig ) {
$this->pageConfig = $pageConfig;
}
/**
* Set the page content language override.
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param Bcp47Code $language
* @return void
*/
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
public function setPageLanguageOverride( Bcp47Code $language ) {
$this->pageLanguageOverride = $language;
}
/**
* Perform variant conversion on a PageBundle object.
*
* @param PageBundle $pageBundle
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param Bcp47Code $targetVariant
* @param ?Bcp47Code $sourceVariant
*
* @return PageBundle The converted PageBundle, or the object passed in as
* $pageBundle if the conversion is not supported.
* @throws HttpException
*/
public function convertPageBundleVariant(
PageBundle $pageBundle,
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
Bcp47Code $targetVariant,
?Bcp47Code $sourceVariant = null
): PageBundle {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
[ $pageLanguage, $sourceVariant ] =
$this->getBaseAndSourceLanguage( $pageBundle, $sourceVariant );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
if ( !$this->siteConfig->langConverterEnabledBcp47( $pageLanguage ) ) {
// If the language doesn't support variants, just return the content unmodified.
return $pageBundle;
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$pageConfig = $this->getPageConfig( $pageLanguage, $sourceVariant );
if ( $this->parsoid->implementsLanguageConversionBcp47( $pageConfig, $targetVariant ) ) {
return $this->parsoid->pb2pb(
$pageConfig, 'variant', $pageBundle,
[
'variant' => [
'source' => $sourceVariant,
'target' => $targetVariant,
]
]
);
} else {
if ( !$this->isFallbackLanguageConverterEnabled ) {
// Fallback variant conversion is not enabled, return the page bundle as is.
return $pageBundle;
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
// LanguageConverter::hasVariant and LanguageConverter::convertTo
// could take a string|Bcp47Code in the future, which would
// allow us to avoid the $targetVariantCode conversion here.
$baseLanguage = $this->languageFactory->getParentLanguage( $targetVariant );
$languageConverter = $this->languageConverterFactory->getLanguageConverter( $baseLanguage );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$targetVariantCode = $this->languageFactory->getLanguage( $targetVariant )->getCode();
if ( $languageConverter->hasVariant( $targetVariantCode ) ) {
Make ParsoidOutputAccess a wrapper over ParserOutputAccess * Updated ParserOutput to set Parsoid render ids that REST API functionality expects in ParserOutput objects. * CacheThresholdTime functionality no longer exists since it was implemented in ParsoidOutputAccess and ParserOutputAccess doesn't support it. This is tracked in T346765. * Enforce the constraint that uncacheable parses are only for fake or mutable revisions. Updated tests that violated this constraint to use 'getParseOutput' instead of calling the parse method directly. * Had to make some changes in ParsoidParser around use of preferredVariant passed to Parsoid. I also left some TODO comments for future fixes. T267067 is also relevant here. PARSOID-SPECIFIC OPTIONS: * logLinterData: linter data is always logged by default -- removed support to disable it. Linter extension handles stale lints properly and it is better to let it handle it rather than add special cases to the API. * offsetType: Moved this support to ParsoidHandler as a post-processing of byte-offset output. This eliminates the need to support this Parsoid-specific options in the ContentHandler hierarchies. * body_only / wrapSections: Handled this in HtmlOutputRendererHelper as a post-processing of regular output by removing sections and returning the body content only. This does result in some useless section-wrapping work with Parsoid, but the simplification is probably worth it. If in the future, we support Parsoid-specific options in the ContentHandler hierarchy, we could re-introduce this. But, in any case, this "fragment" flavor options is likely to get moved out of core into the VisualEditor extension code. DEPLOYMENT: * This patch changes the cache key by setting the useParsoid option in ParserOptions. The parent patch handles this to ensure we don't encounter a cold cache on deploy. TESTS: * Updated tests and mocks to reflect new reality. * Do we need any new tests? Bug: T332931 Change-Id: Ic9b7cc0fcf365e772b7d080d76a065e3fd585f80
2023-08-29 20:13:43 +00:00
// NOTE: This is not a convert() because we have the exact desired variant
// and don't need to compute a preferred variant based on a base language.
// Also see T267067 for why convert() should be avoided.
$convertedHtml = $languageConverter->convertTo( $pageBundle->html, $targetVariantCode );
$pageVariant = $targetVariant;
} else {
// No conversion possible - pass through original HTML in original language
$convertedHtml = $pageBundle->html;
$pageVariant = $pageConfig->getPageLanguageBcp47();
}
// Add a note so that we can identify what was used to perform the variant conversion
$msg = "<!-- Variant conversion performed using the core LanguageConverter -->";
$convertedHtml = $msg . $convertedHtml;
// NOTE: Keep this in sync with code in Parsoid.php in Parsoid repo
// Add meta information that Parsoid normally adds
$headers = [
'content-language' => $pageVariant->toBcp47Code(),
'vary' => [ 'Accept', 'Accept-Language' ]
];
$doc = DOMUtils::parseHTML( '' );
$doc->appendChild( $doc->createElement( 'head' ) );
DOMUtils::addHttpEquivHeaders( $doc, $headers );
$docElt = $doc->documentElement;
'@phan-var Element $docElt';
$docHtml = DOMCompat::getOuterHTML( $docElt );
$convertedHtml = preg_replace( "#</body>#", $docHtml, "$convertedHtml</body>" );
return new PageBundle(
$convertedHtml, [], [], $pageBundle->version, $headers
);
}
}
/**
* Perform variant conversion on a ParserOutput object.
*
* @param ParserOutput $parserOutput
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param Bcp47Code $targetVariant
* @param ?Bcp47Code $sourceVariant
*
* @return ParserOutput
*/
public function convertParserOutputVariant(
ParserOutput $parserOutput,
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
Bcp47Code $targetVariant,
?Bcp47Code $sourceVariant = null
): ParserOutput {
$pageBundle = PageBundleParserOutputConverter::pageBundleFromParserOutput( $parserOutput );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$modifiedPageBundle = $this->convertPageBundleVariant( $pageBundle, $targetVariant, $sourceVariant );
return PageBundleParserOutputConverter::parserOutputFromPageBundle( $modifiedPageBundle, $parserOutput );
}
/**
* Disable fallback language variant converter
* @return void
*/
public function disableFallbackLanguageConverter(): void {
$this->isFallbackLanguageConverterEnabled = false;
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
private function getPageConfig( Bcp47Code $pageLanguage, ?Bcp47Code $sourceVariant ): PageConfig {
if ( $this->pageConfig ) {
return $this->pageConfig;
}
try {
$this->pageConfig = $this->pageConfigFactory->create(
$this->pageIdentity,
null,
null,
null,
$pageLanguage
);
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
if ( $sourceVariant ) {
$this->pageConfig->setVariantBcp47( $sourceVariant );
}
} catch ( RevisionAccessException $exception ) {
// TODO: Throw a different exception, this class should not know
// about HTTP status codes.
throw new LocalizedHttpException( new MessageValue( "rest-specified-revision-unavailable" ), 404 );
}
return $this->pageConfig;
}
/**
* Try to determine the page's language code as follows:
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* First consider any value set by calling ::setPageLanguageOverride();
* this would have come from a Content-Language header.
*
* If ::setPageLanguageOverride() has not been called, check for a
* content-language header in $pageBundle, which should be
* equivalent. These are used when the title/article doesn't
* (yet) exist.
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* If these are not given, use the $default if given; this is used
* to allow additional parameters to the request to be used as
* fallbacks.
*
* If we don't have $default, but we do have a PageConfig in
* $this->pageConfig, return $this->pageConfig->getPageLanguage().
*
* Finally, fall back to $this->pageTitle->getPageLanguage().
*
* @param PageBundle $pageBundle
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param Bcp47Code|null $default A default language, used after
* Content-Language but before PageConfig/Title lookup.
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @return Bcp47Code the page language; may be a variant.
*/
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
private function getPageLanguage( PageBundle $pageBundle, ?Bcp47Code $default = null ): Bcp47Code {
// If a language was set by calling setPageLanguageOverride(), always use it!
if ( $this->pageLanguageOverride ) {
return $this->pageLanguageOverride;
}
// If the page bundle contains a language code, use that.
$pageBundleLanguage = $pageBundle->headers[ 'content-language' ] ?? null;
if ( $pageBundleLanguage ) {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
// The HTTP header will contain a BCP-47 language code, not a
// mediawiki-internal one.
return new Bcp47CodeValue( $pageBundleLanguage );
}
// NOTE: Use explicit default *before* we try PageBundle, because PageConfig::getPageLanguage()
// falls back to Title::getPageLanguage(). If we did that first, $default would never be used.
if ( $default ) {
return $default;
}
// If we have a PageConfig, we can ask it for the page's language. Note that this will fall back to
// Title::getPageLanguage(), so it has to be the last thing we try.
if ( $this->pageConfig ) {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
return $this->pageConfig->getPageLanguageBcp47();
}
// Finally, just go by the code associated with the title. This may come from the database or
// it may be determined based on the title itself.
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
return $this->pageTitle->getPageLanguage();
}
/**
* Determine the codes of the base language and the source variant.
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* The base language will be used to find the appropriate LanguageConverter.
* It should never be a variant.
*
* The source variant will be used to instruct the LanguageConverter.
* It should always be a variant (or null to trigger auto-detection of
* the source variant).
*
* @param PageBundle $pageBundle
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param ?Bcp47Code $sourceLanguage
*
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @return array{0:Bcp47Code,1:?Bcp47Code} [ Bcp47Code $pageLanguage, ?Bcp47Code $sourceLanguage ]
*/
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
private function getBaseAndSourceLanguage( PageBundle $pageBundle, ?Bcp47Code $sourceLanguage ): array {
// Try to determine the language code associated with the content of the page.
// The result may be a variant code.
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$baseLanguage = $this->getPageLanguage( $pageBundle, $sourceLanguage );
// To find out if $baseLanguage is actually a variant, get the parent language and compare.
$parentLang = $this->languageFactory->getParentLanguage( $baseLanguage );
// If $parentLang is not the same language as $baseLanguage, this means that
// $baseLanguage is a variant. In that case, set $sourceLanguage to that
// variant (unless $sourceLanguage is already set), and set $baseLanguage
// to the $parentLang
if ( $parentLang && strcasecmp( $parentLang->toBcp47Code(), $baseLanguage->toBcp47Code() ) !== 0 ) {
if ( !$sourceLanguage ) {
$sourceLanguage = $baseLanguage;
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$baseLanguage = $parentLang;
}
if ( $sourceLanguage !== null ) {
$parentConverter = $this->languageConverterFactory->getLanguageConverter( $parentLang );
// If the source variant isn't actually a variant, trigger auto-detection
$sourceIsVariant = (
strcasecmp( $parentLang->toBcp47Code(), $sourceLanguage->toBcp47Code() ) !== 0 &&
$parentConverter->hasVariant(
LanguageCode::bcp47ToInternal( $sourceLanguage->toBcp47Code() )
)
);
if ( !$sourceIsVariant ) {
$sourceLanguage = null;
}
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
return [ $baseLanguage, $sourceLanguage ];
}
}