wiki.techinc.nl/includes/parser/Parsoid/LanguageVariantConverter.php
Abijeet 715080cfd5 LanguageVariantConverter: Use content language code from HTTP header
Use the content language from the header, and give that the highest
priority when identifying the page language.

Bug: T317019
Change-Id: Ibb0671f1b873ef83a4d53824a9c4c17726e68635
2022-10-07 20:28:57 +05:30

188 lines
4.8 KiB
PHP

<?php
namespace MediaWiki\Parser\Parsoid;
use InvalidArgumentException;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Parser\Parsoid\Config\PageConfigFactory;
use MediaWiki\Rest\HttpException;
use MediaWiki\Revision\RevisionAccessException;
use ParserOutput;
use Title;
use TitleFactory;
use Wikimedia\Parsoid\Config\PageConfig;
use Wikimedia\Parsoid\Config\SiteConfig;
use Wikimedia\Parsoid\Core\PageBundle;
use Wikimedia\Parsoid\Parsoid;
/**
* @since 1.40
* @unstable should be marked stable before 1.40 release
*/
class LanguageVariantConverter {
/** @var PageConfigFactory */
private $pageConfigFactory;
/** @var PageConfig */
private $pageConfig;
/** @var PageIdentity */
private $pageIdentity;
/** @var Title */
private $pageTitle;
/** @var Parsoid */
private $parsoid;
/** @var array */
private $parsoidSettings;
/** @var SiteConfig */
private $siteConfig;
/** @var TitleFactory */
private $titleFactory;
/** @var string */
private $pageContentLanguage;
public function __construct(
PageIdentity $pageIdentity,
PageConfigFactory $pageConfigFactory,
Parsoid $parsoid,
array $parsoidSettings,
SiteConfig $siteConfig,
TitleFactory $titleFactory
) {
$this->pageConfigFactory = $pageConfigFactory;
$this->pageIdentity = $pageIdentity;
$this->parsoid = $parsoid;
$this->parsoidSettings = $parsoidSettings;
$this->siteConfig = $siteConfig;
$this->titleFactory = $titleFactory;
// @phan-suppress-next-line PhanPossiblyNullTypeMismatchProperty
$this->pageTitle = $this->titleFactory->castFromPageIdentity( $this->pageIdentity );
}
/**
* 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
*
* @param string $language
* @return void
*/
public function setPageContentLanguage( string $language ) {
$this->pageContentLanguage = $language;
}
/**
* Perform variant conversion on a PageBundle object.
*
* @param PageBundle $pageBundle
* @param string $targetVariantCode
* @param string|null $sourceVariantCode
*
* @return PageBundle
* @throws HttpException
*/
public function convertPageBundleVariant(
PageBundle $pageBundle,
string $targetVariantCode,
string $sourceVariantCode = null
): PageBundle {
$pageLanguageCode = $this->getPageLanguageCode( $pageBundle );
if ( !$this->siteConfig->langConverterEnabledForLanguage( $pageLanguageCode ) ) {
throw new InvalidArgumentException( "LanguageConversion is not supported for $pageLanguageCode." );
}
$pageConfig = $this->getPageConfig( $pageLanguageCode, $sourceVariantCode );
$modifiedPageBundle = $this->parsoid->pb2pb(
$pageConfig, 'variant', $pageBundle,
[
'variant' => [
'source' => $sourceVariantCode,
'target' => $targetVariantCode,
]
]
);
return $modifiedPageBundle;
}
/**
* Perform variant conversion on a ParserOutput object.
*
* @param ParserOutput $parserOutput
* @param string $targetVariantCode
* @param string|null $sourceVariantCode
*
* @return ParserOutput
*/
public function convertParserOutputVariant(
ParserOutput $parserOutput,
string $targetVariantCode,
string $sourceVariantCode = null
): ParserOutput {
$pageBundle = PageBundleParserOutputConverter::pageBundleFromParserOutput( $parserOutput );
$modifiedPageBundle = $this->convertPageBundleVariant( $pageBundle, $targetVariantCode, $sourceVariantCode );
return PageBundleParserOutputConverter::parserOutputFromPageBundle( $modifiedPageBundle );
}
private function getPageConfig( string $pageLanguageCode, ?string $sourceVariantCode ): PageConfig {
if ( $this->pageConfig ) {
return $this->pageConfig;
}
try {
$this->pageConfig = $this->pageConfigFactory->create(
$this->pageIdentity,
null,
null,
null,
$pageLanguageCode,
$this->parsoidSettings
);
if ( $sourceVariantCode ) {
$this->pageConfig->setVariant( $sourceVariantCode );
}
} catch ( RevisionAccessException $exception ) {
// TODO: Throw a different exception, this class should not know
// about HTTP status codes.
throw new HttpException( 'The specified revision is deleted or suppressed.', 404 );
}
return $this->pageConfig;
}
private function getPageLanguageCode( PageBundle $pageBundle ): string {
if ( $this->pageContentLanguage ) {
return $this->pageContentLanguage;
}
$pageBundleLanguage = $pageBundle->headers[ 'content-language' ] ?? null;
if ( $pageBundleLanguage ) {
return $pageBundleLanguage;
}
if ( $this->pageConfig ) {
return $this->pageConfig->getPageLanguage();
}
return $this->pageTitle->getPageLanguage()->getCode();
}
}