From 42442e01ff7e503fd89084d5d82a0586aeaa382f Mon Sep 17 00:00:00 2001 From: Roman Stolar Date: Mon, 9 Aug 2021 16:39:19 +0300 Subject: [PATCH] Move Content::preloadTransform to ContentHandler Update ContentTransformer to access ContentHandler::preLoadTransform through the service. Prepare object to hold a data that required for ContentHandler::preLoadTranform params. This is a fully backwards compatible change. We are doing hard deprecation via MWDebug::detectDeprecatedOverride. However, with the ContentHandler calling Content and Content calling ContentHandler, it doesn't matter whether callers use Content or ContentHandler. This will allow us to naturally convert all callers. Bug: T287157 Change-Id: I89537e1e7d24c6e15252b2b51890a0bd81ea3e6b --- includes/EditPage.php | 8 +- includes/content/AbstractContent.php | 11 +- includes/content/Content.php | 3 +- includes/content/ContentHandler.php | 123 +++++++++++++++--- includes/content/CssContentHandler.php | 13 +- includes/content/JavaScriptContentHandler.php | 13 +- includes/content/JsonContentHandler.php | 13 +- includes/content/TextContentHandler.php | 13 +- .../content/Transform/ContentTransformer.php | 23 ++++ .../Transform/PreloadTransformParams.php | 27 ++++ .../Transform/PreloadTransformParamsValue.php | 50 +++++++ includes/content/WikitextContent.php | 18 --- includes/content/WikitextContentHandler.php | 53 +++++++- .../Transform/ContentTransformerTest.php | 23 ++++ 14 files changed, 332 insertions(+), 59 deletions(-) create mode 100644 includes/content/Transform/PreloadTransformParams.php create mode 100644 includes/content/Transform/PreloadTransformParamsValue.php diff --git a/includes/EditPage.php b/includes/EditPage.php index dc26f7db9bc..b442c664eb1 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -1602,7 +1602,13 @@ class EditPage implements IEditObject { $content = $converted; } - return $content->preloadTransform( $title, $parserOptions, $params ); + $contentTransformer = MediaWikiServices::getInstance()->getContentTransformer(); + return $contentTransformer->preloadTransform( + $content, + $title, + $parserOptions, + $params + ); } /** diff --git a/includes/content/AbstractContent.php b/includes/content/AbstractContent.php index 09412f652c0..45b62fb0f52 100644 --- a/includes/content/AbstractContent.php +++ b/includes/content/AbstractContent.php @@ -27,6 +27,7 @@ */ use MediaWiki\Content\IContentHandlerFactory; +use MediaWiki\Content\Transform\PreloadTransformParamsValue; use MediaWiki\Content\Transform\PreSaveTransformParamsValue; use MediaWiki\MediaWikiServices; @@ -420,9 +421,9 @@ abstract class AbstractContent implements Content { } /** - * @stable to override * @since 1.21 - * + * @deprecated since 1.37. Use ContentTransformer::preloadTransform instead. + * Extensions defining a content model should override ContentHandler::preloadTransform. * @param Title $title * @param ParserOptions $popts * @param array $params @@ -431,7 +432,11 @@ abstract class AbstractContent implements Content { * @see Content::preloadTransform */ public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) { - return $this; + $pltParams = new PreloadTransformParamsValue( $title, $popts, $params ); + return $this->getContentHandler()->preloadTransform( + $this, + $pltParams + ); } /** diff --git a/includes/content/Content.php b/includes/content/Content.php index def770585b8..df89b3cf916 100644 --- a/includes/content/Content.php +++ b/includes/content/Content.php @@ -415,7 +415,8 @@ interface Content { * object if no transformations apply). * * @since 1.21 - * + * @deprecated since 1.37 Use ContentTransformer::preloadTransform + * and override ContentHandler::preloadTransform. * @param Title $title * @param ParserOptions $parserOptions * @param array $params diff --git a/includes/content/ContentHandler.php b/includes/content/ContentHandler.php index fbf75edb954..c12912a021d 100644 --- a/includes/content/ContentHandler.php +++ b/includes/content/ContentHandler.php @@ -26,6 +26,7 @@ * @author Daniel Kinzler */ +use MediaWiki\Content\Transform\PreloadTransformParams; use MediaWiki\Content\Transform\PreSaveTransformParams; use MediaWiki\HookContainer\ProtectedHookAccessorTrait; use MediaWiki\Logger\LoggerFactory; @@ -1546,37 +1547,117 @@ abstract class ContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( !$shouldCallDeprecatedMethod ) { + return $content; } - return $content; + + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } /** - * If provided content overrides deprecated Content::preSaveTransform, - * call it and return. Otherwise return null. - * @internal only core ContentHandler implementations need to call this. + * Returns a $content object with preload transformations applied (or the same + * object if no transformations apply). + * + * @note Not stable to call other then from ContentHandler hierarchy. + * Callers need to use ContentTransformer::preLoadTransform. + * @stable to override + * @since 1.37 * * @param Content $content - * @param PreSaveTransformParams $pstParams - * @return ?Content + * @param PreloadTransformParams $pltParams + * + * @return Content */ - protected function maybeCallDeprecatedContentPST( + public function preloadTransform( Content $content, - PreSaveTransformParams $pstParams - ): ?Content { - $contentOverridesTransform = MWDebug::detectDeprecatedOverride( + PreloadTransformParams $pltParams + ): Content { + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pltParams + ); + + if ( !$shouldCallDeprecatedMethod ) { + return $content; + } + + return $this->callDeprecatedContentPLT( + $content, + $pltParams + ); + } + + /** + * Check if we need to provide content overrides deprecated Content method. + * + * @internal only core ContentHandler implementations need to call this. + * @param Content $content + * @param PreSaveTransformParams|PreloadTransformParams $params + * @return bool + */ + protected function shouldCallDeprecatedContentTransformMethod( + Content $content, + $params + ): bool { + $method = $params instanceof PreSaveTransformParams + ? "preSaveTransform" + : "preloadTransform"; + return MWDebug::detectDeprecatedOverride( $content, AbstractContent::class, - 'preSaveTransform' + $method + ); + } + + /** + * Provided content overrides deprecated Content::preSaveTransform, + * call it and return. + * @internal only core ContentHandler implementations need to call this. + * @param Content $content + * @param PreSaveTransformParams $params + * @return Content + */ + protected function callDeprecatedContentPST( + Content $content, + PreSaveTransformParams $params + ): Content { + $services = MediaWikiServices::getInstance(); + $legacyUser = $services->getUserFactory()->newFromUserIdentity( $params->getUser() ); + $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() ); + + return $content->preSaveTransform( + $legacyTitle, + $legacyUser, + $params->getParserOptions() + ); + } + + /** + * If provided content overrides deprecated Content::preloadTransform, + * call it and return. + * @internal only core ContentHandler implementations need to call this. + * @param Content $content + * @param PreloadTransformParams $params + * @return Content + */ + protected function callDeprecatedContentPLT( + Content $content, + PreloadTransformParams $params + ): Content { + $services = MediaWikiServices::getInstance(); + $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() ); + return $content->preloadTransform( + $legacyTitle, + $params->getParserOptions(), + $params->getParams() ); - if ( $contentOverridesTransform ) { - $services = MediaWikiServices::getInstance(); - $legacyUser = $services->getUserFactory()->newFromUserIdentity( $pstParams->getUser() ); - $legacyTitle = $services->getTitleFactory()->castFromPageReference( $pstParams->getPage() ); - return $content->preSaveTransform( $legacyTitle, $legacyUser, $pstParams->getParserOptions() ); - } - return null; } } diff --git a/includes/content/CssContentHandler.php b/includes/content/CssContentHandler.php index 092d36d6cd5..06bc41c609f 100644 --- a/includes/content/CssContentHandler.php +++ b/includes/content/CssContentHandler.php @@ -66,9 +66,16 @@ class CssContentHandler extends CodeContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } '@phan-var CssContent $content'; diff --git a/includes/content/JavaScriptContentHandler.php b/includes/content/JavaScriptContentHandler.php index 3c30bca5160..c236d5b5450 100644 --- a/includes/content/JavaScriptContentHandler.php +++ b/includes/content/JavaScriptContentHandler.php @@ -67,9 +67,16 @@ class JavaScriptContentHandler extends CodeContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } '@phan-var JavascriptContent $content'; diff --git a/includes/content/JsonContentHandler.php b/includes/content/JsonContentHandler.php index 52007fd4901..962c838a313 100644 --- a/includes/content/JsonContentHandler.php +++ b/includes/content/JsonContentHandler.php @@ -51,9 +51,16 @@ class JsonContentHandler extends CodeContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } '@phan-var JsonContent $content'; diff --git a/includes/content/TextContentHandler.php b/includes/content/TextContentHandler.php index 3729b75ea31..9c6c7f8a187 100644 --- a/includes/content/TextContentHandler.php +++ b/includes/content/TextContentHandler.php @@ -166,9 +166,16 @@ class TextContentHandler extends ContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } '@phan-var TextContent $content'; diff --git a/includes/content/Transform/ContentTransformer.php b/includes/content/Transform/ContentTransformer.php index 2229f4b86ba..01288b88702 100644 --- a/includes/content/Transform/ContentTransformer.php +++ b/includes/content/Transform/ContentTransformer.php @@ -45,4 +45,27 @@ class ContentTransformer { return $contentHandler->preSaveTransform( $content, $pstParams ); } + + /** + * Returns a Content object with preload transformations applied (or $content + * if no transformations apply). + * + * @param Content $content + * @param PageReference $page + * @param ParserOptions $parserOptions + * @param array $params + * + * @return Content + */ + public function preloadTransform( + Content $content, + PageReference $page, + ParserOptions $parserOptions, + array $params = [] + ): Content { + $contentHandler = $this->contentHandlerFactory->getContentHandler( $content->getModel() ); + $pltParams = new PreloadTransformParamsValue( $page, $parserOptions, $params ); + + return $contentHandler->preloadTransform( $content, $pltParams ); + } } diff --git a/includes/content/Transform/PreloadTransformParams.php b/includes/content/Transform/PreloadTransformParams.php new file mode 100644 index 00000000000..92277904c66 --- /dev/null +++ b/includes/content/Transform/PreloadTransformParams.php @@ -0,0 +1,27 @@ +page = $page; + $this->parserOptions = $parserOptions; + $this->params = $params; + } + + /** + * + * @return PageReference + */ + public function getPage(): PageReference { + return $this->page; + } + + /** + * + * @return array + */ + public function getParams(): array { + return $this->params; + } + + /** + * + * @return ParserOptions + */ + public function getParserOptions(): ParserOptions { + return $this->parserOptions; + } +} diff --git a/includes/content/WikitextContent.php b/includes/content/WikitextContent.php index df4222f0a6b..cf5db675098 100644 --- a/includes/content/WikitextContent.php +++ b/includes/content/WikitextContent.php @@ -141,24 +141,6 @@ class WikitextContent extends TextContent { return new static( $text ); } - /** - * Returns a Content object with preload transformations applied (or this - * object if no transformations apply). - * - * @param Title $title - * @param ParserOptions $popts - * @param array $params - * - * @return Content - */ - public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) { - $text = $this->getText(); - $plt = MediaWikiServices::getInstance()->getParser() - ->getPreloadText( $text, $title, $popts, $params ); - - return new static( $plt ); - } - /** * Extract the redirect target and the remaining text on the page. * diff --git a/includes/content/WikitextContentHandler.php b/includes/content/WikitextContentHandler.php index d1f543406d2..66d94a80b78 100644 --- a/includes/content/WikitextContentHandler.php +++ b/includes/content/WikitextContentHandler.php @@ -23,6 +23,7 @@ * @ingroup Content */ +use MediaWiki\Content\Transform\PreloadTransformParams; use MediaWiki\Content\Transform\PreSaveTransformParams; use MediaWiki\Languages\LanguageNameUtils; use MediaWiki\MediaWikiServices; @@ -193,9 +194,16 @@ class WikitextContentHandler extends TextContentHandler { Content $content, PreSaveTransformParams $pstParams ): Content { - $deprecatedContent = $this->maybeCallDeprecatedContentPST( $content, $pstParams ); - if ( $deprecatedContent ) { - return $deprecatedContent; + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pstParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPST( + $content, + $pstParams + ); } '@phan-var WikitextContent $content'; @@ -219,4 +227,43 @@ class WikitextContentHandler extends TextContentHandler { $ret->setPreSaveTransformFlags( $parser->getOutput()->getAllFlags() ); return $ret; } + + /** + * Returns a Content object with preload transformations applied (or this + * object if no transformations apply). + * + * @param Content $content + * @param PreloadTransformParams $pltParams + * + * @return Content + */ + public function preloadTransform( + Content $content, + PreloadTransformParams $pltParams + ): Content { + $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod( + $content, + $pltParams + ); + + if ( $shouldCallDeprecatedMethod ) { + return $this->callDeprecatedContentPLT( + $content, + $pltParams + ); + } + + '@phan-var WikitextContent $content'; + + $text = $content->getText(); + $plt = MediaWikiServices::getInstance()->getParser()->getPreloadText( + $text, + $pltParams->getPage(), + $pltParams->getParserOptions(), + $pltParams->getParams() + ); + + $contentClass = $this->getContentClass(); + return new $contentClass( $plt ); + } } diff --git a/tests/phpunit/includes/content/Transform/ContentTransformerTest.php b/tests/phpunit/includes/content/Transform/ContentTransformerTest.php index 7c1cf19e5b6..9b99236793f 100644 --- a/tests/phpunit/includes/content/Transform/ContentTransformerTest.php +++ b/tests/phpunit/includes/content/Transform/ContentTransformerTest.php @@ -28,4 +28,27 @@ class ContentTransformerTest extends MediaWikiIntegrationTestCase { $newContent = $services->getContentTransformer()->preSaveTransform( $content, $title, $user, $options ); $this->assertSame( $expectedContainText, $newContent->serialize() ); } + + public function preloadTransformProvider() { + return [ + [ + new WikitextContent( '{{Foo}} censored information ' ), + '{{Foo}} information ' + ], + ]; + } + + /** + * @covers MediaWiki\Content\Transform\ContentTransformer::preloadTransform + * + * @dataProvider preloadTransformProvider + */ + public function testPreloadTransform( $content, $expectedContainText ) { + $services = MediaWikiServices::getInstance(); + $title = Title::newFromText( 'Test' ); + $options = ParserOptions::newFromAnon(); + + $newContent = $services->getContentTransformer()->preloadTransform( $content, $title, $options ); + $this->assertSame( $expectedContainText, $newContent->serialize() ); + } }