Use services in WikitextContentHandler

Change-Id: I626b5ee9a070ad3a97ab9ac9f44cb7003d68bf13
This commit is contained in:
daniel 2022-08-24 14:55:03 +02:00 committed by C. Scott Ananian
parent 6c175865f4
commit 090ec5777d
10 changed files with 178 additions and 35 deletions

View file

@ -1994,7 +1994,7 @@ config-schema:
- 1.40: Added - 1.40: Added
ContentHandlers: ContentHandlers:
default: default:
wikitext: WikitextContentHandler wikitext: { class: WikitextContentHandler, services: [TitleFactory, ParserFactory, GlobalIdGenerator, LanguageNameUtils, MagicWordFactory] }
javascript: JavaScriptContentHandler javascript: JavaScriptContentHandler
json: JsonContentHandler json: JsonContentHandler
css: CssContentHandler css: CssContentHandler
@ -2003,7 +2003,7 @@ config-schema:
type: object type: object
description: |- description: |-
Plugins for page content model handling. Plugins for page content model handling.
Each entry in the array maps a model id to a class name or callback Each entry in the array maps a model id to an ObjectFactory specification
that creates an instance of the appropriate ContentHandler subclass. that creates an instance of the appropriate ContentHandler subclass.
@since 1.21 @since 1.21
NamespaceContentModels: NamespaceContentModels:

View file

@ -3260,7 +3260,7 @@ class MainConfigSchema {
/** /**
* Plugins for page content model handling. * Plugins for page content model handling.
* *
* Each entry in the array maps a model id to a class name or callback * Each entry in the array maps a model id to an ObjectFactory specification
* that creates an instance of the appropriate ContentHandler subclass. * that creates an instance of the appropriate ContentHandler subclass.
* *
* @since 1.21 * @since 1.21
@ -3269,7 +3269,16 @@ class MainConfigSchema {
'default' => 'default' =>
[ [
// the usual case // the usual case
CONTENT_MODEL_WIKITEXT => WikitextContentHandler::class, CONTENT_MODEL_WIKITEXT => [
'class' => WikitextContentHandler::class,
'services' => [
'TitleFactory',
'ParserFactory',
'GlobalIdGenerator',
'LanguageNameUtils',
'MagicWordFactory',
],
],
// dumb version, no syntax highlighting // dumb version, no syntax highlighting
CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class, CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class,
// simple implementation, for use by extensions, etc. // simple implementation, for use by extensions, etc.

View file

@ -386,7 +386,16 @@ return [
'TemplateLinksSchemaMigrationStage' => 768, 'TemplateLinksSchemaMigrationStage' => 768,
'ExternalLinksSchemaMigrationStage' => 3, 'ExternalLinksSchemaMigrationStage' => 3,
'ContentHandlers' => [ 'ContentHandlers' => [
'wikitext' => 'WikitextContentHandler', 'wikitext' => [
'class' => 'WikitextContentHandler',
'services' => [
0 => 'TitleFactory',
1 => 'ParserFactory',
2 => 'GlobalIdGenerator',
3 => 'LanguageNameUtils',
4 => 'MagicWordFactory',
],
],
'javascript' => 'JavaScriptContentHandler', 'javascript' => 'JavaScriptContentHandler',
'json' => 'JsonContentHandler', 'json' => 'JsonContentHandler',
'css' => 'CssContentHandler', 'css' => 'CssContentHandler',

View file

@ -27,9 +27,10 @@ use MediaWiki\Content\Renderer\ContentParseParams;
use MediaWiki\Content\Transform\PreloadTransformParams; use MediaWiki\Content\Transform\PreloadTransformParams;
use MediaWiki\Content\Transform\PreSaveTransformParams; use MediaWiki\Content\Transform\PreSaveTransformParams;
use MediaWiki\Languages\LanguageNameUtils; use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\MediaWikiServices;
use MediaWiki\Parser\ParserOutputFlags; use MediaWiki\Parser\ParserOutputFlags;
use MediaWiki\Revision\RevisionRecord; use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Title\TitleFactory;
use Wikimedia\UUID\GlobalIdGenerator;
/** /**
* Content handler for wiki text pages. * Content handler for wiki text pages.
@ -38,8 +39,44 @@ use MediaWiki\Revision\RevisionRecord;
*/ */
class WikitextContentHandler extends TextContentHandler { class WikitextContentHandler extends TextContentHandler {
public function __construct( $modelId = CONTENT_MODEL_WIKITEXT ) { /** @var TitleFactory */
private $titleFactory;
/** @var ParserFactory */
private $parserFactory;
/** @var GlobalIdGenerator */
private $globalIdGenerator;
/** @var LanguageNameUtils */
private $languageNameUtils;
/** @var MagicWordFactory */
private $magicWordFactory;
/**
* @param string $modelId
* @param TitleFactory $titleFactory
* @param ParserFactory $parserFactory
* @param GlobalIdGenerator $globalIdGenerator
* @param LanguageNameUtils $languageNameUtils
* @param MagicWordFactory $magicWordFactory
*/
public function __construct(
string $modelId,
TitleFactory $titleFactory,
ParserFactory $parserFactory,
GlobalIdGenerator $globalIdGenerator,
LanguageNameUtils $languageNameUtils,
MagicWordFactory $magicWordFactory
) {
// $modelId should always be CONTENT_MODEL_WIKITEXT
parent::__construct( $modelId, [ CONTENT_FORMAT_WIKITEXT ] ); parent::__construct( $modelId, [ CONTENT_FORMAT_WIKITEXT ] );
$this->titleFactory = $titleFactory;
$this->parserFactory = $parserFactory;
$this->globalIdGenerator = $globalIdGenerator;
$this->languageNameUtils = $languageNameUtils;
$this->magicWordFactory = $magicWordFactory;
} }
protected function getContentClass() { protected function getContentClass() {
@ -59,14 +96,11 @@ class WikitextContentHandler extends TextContentHandler {
public function makeRedirectContent( Title $destination, $text = '' ) { public function makeRedirectContent( Title $destination, $text = '' ) {
$optionalColon = ''; $optionalColon = '';
$services = MediaWikiServices::getInstance();
if ( $destination->getNamespace() === NS_CATEGORY ) { if ( $destination->getNamespace() === NS_CATEGORY ) {
$optionalColon = ':'; $optionalColon = ':';
} else { } else {
$iw = $destination->getInterwiki(); $iw = $destination->getInterwiki();
if ( $iw && $services if ( $iw && $this->languageNameUtils->getLanguageName( $iw,
->getLanguageNameUtils()
->getLanguageName( $iw,
LanguageNameUtils::AUTONYMS, LanguageNameUtils::AUTONYMS,
LanguageNameUtils::DEFINED ) LanguageNameUtils::DEFINED )
) { ) {
@ -74,7 +108,7 @@ class WikitextContentHandler extends TextContentHandler {
} }
} }
$mwRedir = $services->getMagicWordFactory()->get( 'redirect' ); $mwRedir = $this->magicWordFactory->get( 'redirect' );
$redirectText = $mwRedir->getSynonym( 0 ) . $redirectText = $mwRedir->getSynonym( 0 ) .
' [[' . $optionalColon . $destination->getFullText() . ']]'; ' [[' . $optionalColon . $destination->getFullText() . ']]';
@ -131,7 +165,14 @@ class WikitextContentHandler extends TextContentHandler {
* @return FileContentHandler * @return FileContentHandler
*/ */
protected function getFileHandler() { protected function getFileHandler() {
return new FileContentHandler(); return new FileContentHandler(
$this->getModelID(),
$this->titleFactory,
$this->parserFactory,
$this->globalIdGenerator,
$this->languageNameUtils,
$this->magicWordFactory
);
} }
public function getFieldsForSearchIndex( SearchEngine $engine ) { public function getFieldsForSearchIndex( SearchEngine $engine ) {
@ -216,10 +257,9 @@ class WikitextContentHandler extends TextContentHandler {
} }
'@phan-var WikitextContent $content'; '@phan-var WikitextContent $content';
$text = $content->getText(); $text = $content->getText();
$parser = MediaWikiServices::getInstance()->getParserFactory()->getInstance(); $parser = $this->parserFactory->getInstance();
$pst = $parser->preSaveTransform( $pst = $parser->preSaveTransform(
$text, $text,
$pstParams->getPage(), $pstParams->getPage(),
@ -263,9 +303,9 @@ class WikitextContentHandler extends TextContentHandler {
} }
'@phan-var WikitextContent $content'; '@phan-var WikitextContent $content';
$text = $content->getText(); $text = $content->getText();
$plt = MediaWikiServices::getInstance()->getParserFactory()->getInstance()
$plt = $this->parserFactory->getInstance()
->getPreloadText( ->getPreloadText(
$text, $text,
$pltParams->getPage(), $pltParams->getPage(),
@ -292,15 +332,15 @@ class WikitextContentHandler extends TextContentHandler {
ParserOutput &$parserOutput ParserOutput &$parserOutput
) { ) {
'@phan-var WikitextContent $content'; '@phan-var WikitextContent $content';
$services = MediaWikiServices::getInstance(); $title = $this->titleFactory->castFromPageReference( $cpoParams->getPage() );
$title = $services->getTitleFactory()->castFromPageReference( $cpoParams->getPage() );
$parserOptions = $cpoParams->getParserOptions(); $parserOptions = $cpoParams->getParserOptions();
$revId = $cpoParams->getRevId(); $revId = $cpoParams->getRevId();
[ $redir, $text ] = $content->getRedirectTargetAndText(); [ $redir, $text ] = $content->getRedirectTargetAndText();
$parserOutput = $services->getParserFactory()->getInstance()
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here $parser = $this->parserFactory->getInstance();
->parse( $text, $title, $parserOptions, true, true, $revId ); // @phan-suppress-next-line PhanTypeMismatchArgumentNullable castFrom does not return null here
$parserOutput = $parser->parse( $text, $title, $parserOptions, true, true, $revId );
// Add redirect indicator at the top // Add redirect indicator at the top
if ( $redir ) { if ( $redir ) {

View file

@ -587,7 +587,16 @@ class DerivedPageDataUpdaterTest extends MediaWikiIntegrationTestCase {
$this->overrideConfigValue( $this->overrideConfigValue(
MainConfigNames::ContentHandlers, MainConfigNames::ContentHandlers,
[ [
CONTENT_MODEL_WIKITEXT => WikitextContentHandler::class, CONTENT_MODEL_WIKITEXT => [
'class' => WikitextContentHandler::class,
'services' => [
'TitleFactory',
'ParserFactory',
'GlobalIdGenerator',
'LanguageNameUtils',
'MagicWordFactory',
],
],
'testing' => DummyContentHandlerForTesting::class, 'testing' => DummyContentHandlerForTesting::class,
] ]
); );

View file

@ -1,10 +1,13 @@
<?php <?php
use MediaWiki\Content\ValidationParams; use MediaWiki\Content\ValidationParams;
use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\MainConfigNames; use MediaWiki\MainConfigNames;
use MediaWiki\Page\PageIdentity; use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\PageIdentityValue; use MediaWiki\Page\PageIdentityValue;
use MediaWiki\Title\TitleFactory;
use Wikimedia\TestingAccessWrapper; use Wikimedia\TestingAccessWrapper;
use Wikimedia\UUID\GlobalIdGenerator;
/** /**
* @group ContentHandler * @group ContentHandler
@ -26,7 +29,16 @@ class ContentHandlerTest extends MediaWikiIntegrationTestCase {
12312 => 'testing', 12312 => 'testing',
], ],
MainConfigNames::ContentHandlers => [ MainConfigNames::ContentHandlers => [
CONTENT_MODEL_WIKITEXT => WikitextContentHandler::class, CONTENT_MODEL_WIKITEXT => [
'class' => WikitextContentHandler::class,
'services' => [
'TitleFactory',
'ParserFactory',
'GlobalIdGenerator',
'LanguageNameUtils',
'MagicWordFactory',
],
],
CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class, CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class,
CONTENT_MODEL_JSON => JsonContentHandler::class, CONTENT_MODEL_JSON => JsonContentHandler::class,
CONTENT_MODEL_CSS => CssContentHandler::class, CONTENT_MODEL_CSS => CssContentHandler::class,
@ -487,7 +499,14 @@ class ContentHandlerTest extends MediaWikiIntegrationTestCase {
] ); ] );
// test default renderer // test default renderer
$contentHandler = new WikitextContentHandler( CONTENT_MODEL_WIKITEXT ); $contentHandler = new WikitextContentHandler(
CONTENT_MODEL_WIKITEXT,
$this->createMock( TitleFactory::class ),
$this->createMock( ParserFactory::class ),
$this->createMock( GlobalIdGenerator::class ),
$this->createMock( LanguageNameUtils::class ),
$this->createMock( MagicWordFactory::class )
);
$slotDiffRenderer = $contentHandler->getSlotDiffRenderer( RequestContext::getMain() ); $slotDiffRenderer = $contentHandler->getSlotDiffRenderer( RequestContext::getMain() );
$this->assertInstanceOf( TextSlotDiffRenderer::class, $slotDiffRenderer ); $this->assertInstanceOf( TextSlotDiffRenderer::class, $slotDiffRenderer );
} }

View file

@ -13,7 +13,16 @@ class RegistrationContentHandlerFactoryToMediaWikiServicesTest extends MediaWiki
$this->overrideConfigValue( $this->overrideConfigValue(
MainConfigNames::ContentHandlers, MainConfigNames::ContentHandlers,
[ [
CONTENT_MODEL_WIKITEXT => WikitextContentHandler::class, CONTENT_MODEL_WIKITEXT => [
'class' => WikitextContentHandler::class,
'services' => [
'TitleFactory',
'ParserFactory',
'GlobalIdGenerator',
'LanguageNameUtils',
'MagicWordFactory',
],
],
CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class, CONTENT_MODEL_JAVASCRIPT => JavaScriptContentHandler::class,
CONTENT_MODEL_JSON => JsonContentHandler::class, CONTENT_MODEL_JSON => JsonContentHandler::class,
CONTENT_MODEL_CSS => CssContentHandler::class, CONTENT_MODEL_CSS => CssContentHandler::class,

View file

@ -5,7 +5,9 @@ namespace MediaWiki\Tests\Rest\Handler;
use ApiUsageException; use ApiUsageException;
use FormatJson; use FormatJson;
use HashConfig; use HashConfig;
use MagicWordFactory;
use MediaWiki\Content\IContentHandlerFactory; use MediaWiki\Content\IContentHandlerFactory;
use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\Rest\Handler\UpdateHandler; use MediaWiki\Rest\Handler\UpdateHandler;
use MediaWiki\Rest\LocalizedHttpException; use MediaWiki\Rest\LocalizedHttpException;
use MediaWiki\Rest\RequestData; use MediaWiki\Rest\RequestData;
@ -13,13 +15,16 @@ use MediaWiki\Revision\MutableRevisionRecord;
use MediaWiki\Revision\RevisionLookup; use MediaWiki\Revision\RevisionLookup;
use MediaWiki\Revision\SlotRecord; use MediaWiki\Revision\SlotRecord;
use MediaWiki\Tests\Unit\DummyServicesTrait; use MediaWiki\Tests\Unit\DummyServicesTrait;
use MediaWiki\Title\TitleFactory;
use MockTitleTrait; use MockTitleTrait;
use ParserFactory;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use Status; use Status;
use Title; use Title;
use Wikimedia\Message\MessageValue; use Wikimedia\Message\MessageValue;
use Wikimedia\Message\ParamType; use Wikimedia\Message\ParamType;
use Wikimedia\Message\ScalarParam; use Wikimedia\Message\ScalarParam;
use Wikimedia\UUID\GlobalIdGenerator;
use WikitextContent; use WikitextContent;
use WikitextContentHandler; use WikitextContentHandler;
@ -52,7 +57,14 @@ class UpdateHandlerTest extends \MediaWikiLangTestCase {
$contentHandlerFactory $contentHandlerFactory
->method( 'getContentHandler' ) ->method( 'getContentHandler' )
->willReturn( new WikitextContentHandler() ); ->willReturn( new WikitextContentHandler(
CONTENT_MODEL_WIKITEXT,
$this->createMock( TitleFactory::class ),
$this->createMock( ParserFactory::class ),
$this->createMock( GlobalIdGenerator::class ),
$this->createMock( LanguageNameUtils::class ),
$this->createMock( MagicWordFactory::class )
) );
// DummyServicesTrait::getDummyMediaWikiTitleCodec // DummyServicesTrait::getDummyMediaWikiTitleCodec
$titleCodec = $this->getDummyMediaWikiTitleCodec(); $titleCodec = $this->getDummyMediaWikiTitleCodec();

View file

@ -1,5 +1,18 @@
<?php <?php
namespace MediaWiki\Tests\Unit;
use FileContentHandler;
use MagicWordFactory;
use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\Title\TitleFactory;
use MediaWikiUnitTestCase;
use ParserFactory;
use SearchEngine;
use SearchIndexField;
use SearchIndexFieldDefinition;
use Wikimedia\UUID\GlobalIdGenerator;
/** /**
* @group ContentHandler * @group ContentHandler
* *
@ -14,7 +27,14 @@ class FileContentHandlerTest extends MediaWikiUnitTestCase {
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
$this->handler = new FileContentHandler(); $this->handler = new FileContentHandler(
CONTENT_MODEL_WIKITEXT,
$this->createMock( TitleFactory::class ),
$this->createMock( ParserFactory::class ),
$this->createMock( GlobalIdGenerator::class ),
$this->createMock( LanguageNameUtils::class ),
$this->createMock( MagicWordFactory::class )
);
} }
public function testIndexMapping() { public function testIndexMapping() {

View file

@ -2,11 +2,16 @@
namespace MediaWiki\Tests\Unit; namespace MediaWiki\Tests\Unit;
use MagicWordFactory;
use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\Revision\SlotRecord; use MediaWiki\Revision\SlotRecord;
use MediaWiki\Revision\SlotRenderingProvider; use MediaWiki\Revision\SlotRenderingProvider;
use MediaWiki\Title\TitleFactory;
use MediaWikiUnitTestCase; use MediaWikiUnitTestCase;
use MWException; use MWException;
use ParserFactory;
use Title; use Title;
use Wikimedia\UUID\GlobalIdGenerator;
use WikitextContent; use WikitextContent;
use WikitextContentHandler; use WikitextContentHandler;
@ -18,12 +23,23 @@ use WikitextContentHandler;
*/ */
class WikitextContentHandlerTest extends MediaWikiUnitTestCase { class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
private function newWikitextContentHandler(): WikitextContentHandler {
return new WikitextContentHandler(
CONTENT_MODEL_WIKITEXT,
$this->createMock( TitleFactory::class ),
$this->createMock( ParserFactory::class ),
$this->createMock( GlobalIdGenerator::class ),
$this->createMock( LanguageNameUtils::class ),
$this->createMock( MagicWordFactory::class )
);
}
/** /**
* @covers ::serializeContent * @covers ::serializeContent
*/ */
public function testSerializeContent() { public function testSerializeContent() {
$content = new WikitextContent( 'hello world' ); $content = new WikitextContent( 'hello world' );
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$this->assertEquals( 'hello world', $handler->serializeContent( $content ) ); $this->assertEquals( 'hello world', $handler->serializeContent( $content ) );
$this->assertEquals( $this->assertEquals(
@ -39,7 +55,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
* @covers ::unserializeContent * @covers ::unserializeContent
*/ */
public function testUnserializeContent() { public function testUnserializeContent() {
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$content = $handler->unserializeContent( 'hello world' ); $content = $handler->unserializeContent( 'hello world' );
$this->assertEquals( 'hello world', $content->getText() ); $this->assertEquals( 'hello world', $content->getText() );
@ -55,7 +71,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
* @covers WikitextContentHandler::makeEmptyContent * @covers WikitextContentHandler::makeEmptyContent
*/ */
public function testMakeEmptyContent() { public function testMakeEmptyContent() {
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$content = $handler->makeEmptyContent(); $content = $handler->makeEmptyContent();
$this->assertTrue( $content->isEmpty() ); $this->assertTrue( $content->isEmpty() );
@ -75,7 +91,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
* @covers ::isSupportedFormat * @covers ::isSupportedFormat
*/ */
public function testIsSupportedFormat( $format, $supported ) { public function testIsSupportedFormat( $format, $supported ) {
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$this->assertEquals( $supported, $handler->isSupportedFormat( $format ) ); $this->assertEquals( $supported, $handler->isSupportedFormat( $format ) );
} }
@ -83,7 +99,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
* @covers ::supportsDirectEditing * @covers ::supportsDirectEditing
*/ */
public function testSupportsDirectEditing() { public function testSupportsDirectEditing() {
$handler = new WikiTextContentHandler(); $handler = $this->newWikiTextContentHandler();
$this->assertTrue( $handler->supportsDirectEditing(), 'direct editing is supported' ); $this->assertTrue( $handler->supportsDirectEditing(), 'direct editing is supported' );
} }
@ -94,7 +110,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
$title = $this->createMock( Title::class ); $title = $this->createMock( Title::class );
$content = new WikitextContent( '' ); $content = new WikitextContent( '' );
$srp = $this->createMock( SlotRenderingProvider::class ); $srp = $this->createMock( SlotRenderingProvider::class );
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$updates = $handler->getSecondaryDataUpdates( $title, $content, SlotRecord::MAIN, $srp ); $updates = $handler->getSecondaryDataUpdates( $title, $content, SlotRecord::MAIN, $srp );
@ -106,7 +122,7 @@ class WikitextContentHandlerTest extends MediaWikiUnitTestCase {
*/ */
public function testGetDeletionUpdates() { public function testGetDeletionUpdates() {
$title = $this->createMock( Title::class ); $title = $this->createMock( Title::class );
$handler = new WikitextContentHandler(); $handler = $this->newWikitextContentHandler();
$updates = $handler->getDeletionUpdates( $title, SlotRecord::MAIN ); $updates = $handler->getDeletionUpdates( $title, SlotRecord::MAIN );
$this->assertEquals( [], $updates ); $this->assertEquals( [], $updates );