Mark Content and ContentHandler base classes as extensible

Bug: T247862
Change-Id: I37666c6372bd922768cf426b12951699d890272b
This commit is contained in:
daniel 2020-06-30 18:53:40 +02:00
parent dfbbaecf0f
commit 7b14d2f563
4 changed files with 118 additions and 1 deletions

View file

@ -32,6 +32,8 @@ use MediaWiki\MediaWikiServices;
/**
* Base implementation for content objects.
*
* @stable for subclassing
*
* @ingroup Content
*/
abstract class AbstractContent implements Content {
@ -46,6 +48,8 @@ abstract class AbstractContent implements Content {
protected $model_id;
/**
* @stable for calling
*
* @param string|null $modelId
*
* @since 1.21
@ -153,6 +157,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param string|null $format
@ -166,6 +171,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @return bool
@ -179,6 +185,7 @@ abstract class AbstractContent implements Content {
/**
* Subclasses may override this to implement (light weight) validation.
*
* @stable for overriding
* @since 1.21
*
* @return bool Always true.
@ -201,6 +208,7 @@ abstract class AbstractContent implements Content {
* and true for $that === this. It MUST also return false if $that does not have the same
* content model.
*
* @stable for overriding
* @since 1.21
*
* @param Content|null $that
@ -245,6 +253,8 @@ abstract class AbstractContent implements Content {
*
* @note Do not call this method directly, call equals() instead.
*
* @stable for overriding
*
* @param Content $that
* @return bool
*/
@ -264,6 +274,7 @@ abstract class AbstractContent implements Content {
* They should however make sure to call SecondaryDataUpdates to give extensions
* a chance to inject additional updates.
*
* @stable for overriding
* @since 1.21
*
* @param Title $title
@ -331,6 +342,7 @@ abstract class AbstractContent implements Content {
/**
* Subclasses that implement redirects should override this.
*
* @stable for overriding
* @since 1.21
*
* @return Title|null
@ -371,6 +383,7 @@ abstract class AbstractContent implements Content {
* This default implementation always returns $this.
* Subclasses that implement redirects should override this.
*
* @stable for overriding
* @since 1.21
*
* @param Title $target
@ -384,6 +397,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param string|int $sectionId
@ -396,6 +410,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param string|int|null|bool $sectionId
@ -410,6 +425,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param Title $title
@ -424,6 +440,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param string $header
@ -436,6 +453,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param Title $title
@ -450,6 +468,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param WikiPage $page
@ -469,6 +488,7 @@ abstract class AbstractContent implements Content {
}
/**
* @stable for overriding
* @since 1.21
*
* @param WikiPage $page
@ -488,6 +508,7 @@ abstract class AbstractContent implements Content {
* This default implementation always returns false. Subclasses may override
* this to supply matching logic.
*
* @stable for overriding
* @since 1.21
*
* @param MagicWord $word
@ -504,6 +525,8 @@ abstract class AbstractContent implements Content {
* This base implementation calls the hook ConvertContent to enable custom conversions.
* Subclasses may override this to implement conversion for "their" content model.
*
* @stable for overriding
*
* @param string $toModel
* @param string $lossy
*
@ -536,6 +559,8 @@ abstract class AbstractContent implements Content {
* Subclasses that override getParserOutput() itself should take care to call the
* ContentGetParserOutput hook.
*
* @stable for overriding
*
* @since 1.24
*
* @param Title $title Context title for parsing
@ -582,6 +607,8 @@ abstract class AbstractContent implements Content {
*
* This placeholder implementation always throws an exception.
*
* @stable for overriding
*
* @since 1.24
*
* @param Title $title Context title for parsing

View file

@ -24,7 +24,9 @@
use MediaWiki\MediaWikiServices;
/**
* Content handler for code content such as CSS, JavaScript, JSON, etc
* Content handler for code content such as CSS, JavaScript, JSON, etc.
*
* @stable for subclassing
* @since 1.24
* @ingroup Content
*/
@ -33,6 +35,8 @@ abstract class CodeContentHandler extends TextContentHandler {
/**
* Returns the English language, because code is English, and should be handled as such.
*
* @stable for overriding
*
* @param Title $title
* @param Content|null $content
*
@ -47,6 +51,8 @@ abstract class CodeContentHandler extends TextContentHandler {
/**
* Returns the English language, because code is English, and should be handled as such.
*
* @stable for overriding
*
* @param Title $title
* @param Content|null $content
*
@ -59,6 +65,8 @@ abstract class CodeContentHandler extends TextContentHandler {
}
/**
* @stable for overriding
*
* @return string
* @throws MWException
*/

View file

@ -52,6 +52,8 @@ use Wikimedia\Assert\Assert;
* type), but wikitext content may be represented by a DOM or AST structure in
* the future.
*
* @stable for subclassing
*
* @ingroup Content
*/
abstract class ContentHandler {
@ -348,6 +350,8 @@ abstract class ContentHandler {
* and a list of supported formats. Values for the parameters are typically
* provided as literals by subclass's constructors.
*
* @stable for calling
*
* @param string $modelId (use CONTENT_MODEL_XXX constants).
* @param string[] $formats List for supported serialization formats
* (typically as MIME types)
@ -360,6 +364,8 @@ abstract class ContentHandler {
/**
* Serializes a Content object of the type supported by this ContentHandler.
*
* @stable for overriding
*
* @since 1.21
*
* @param Content $content The Content object to serialize
@ -374,6 +380,8 @@ abstract class ContentHandler {
* Subclasses may override this to perform transformations such as conversion
* of legacy formats or filtering of internal meta-data.
*
* @stable for overriding
*
* @param string $blob The blob to be exported
* @param string|null $format The blob's serialization format
*
@ -386,6 +394,7 @@ abstract class ContentHandler {
/**
* Unserializes a Content object of the type supported by this ContentHandler.
*
* @stable for overriding
* @since 1.21
*
* @param string $blob Serialized form of the content
@ -400,6 +409,7 @@ abstract class ContentHandler {
* Apply import transformation (per default, returns $blob unchanged).
* This gives subclasses an opportunity to transform data blobs on import.
*
* @stable for overriding
* @since 1.24
*
* @param string $blob
@ -415,6 +425,7 @@ abstract class ContentHandler {
* Creates an empty Content object of the type supported by this
* ContentHandler.
*
* @stable for overriding
* @since 1.21
*
* @return Content
@ -431,6 +442,7 @@ abstract class ContentHandler {
* Note that subclasses that override this method to return a Content object
* should also override supportsRedirects() to return true.
*
* @stable for overriding
* @since 1.21
*
* @param Title $destination The page to redirect to.
@ -475,6 +487,7 @@ abstract class ContentHandler {
* serializeContent() and unserializeContent() methods of this
* ContentHandler.
*
* @stable for overriding
* @since 1.21
*
* @return string[] List of serialization formats as MIME type like strings
@ -490,6 +503,7 @@ abstract class ContentHandler {
* This default implementation will return the first element of the array
* of formats that was passed to the constructor.
*
* @stable for overriding
* @since 1.21
*
* @return string The name of the default serialization format as a MIME type
@ -505,6 +519,7 @@ abstract class ContentHandler {
* Note that if $format is null, this method always returns true, because
* null means "use the default format".
*
* @stable for overriding
* @since 1.21
*
* @param string $format The serialization format to check
@ -541,6 +556,7 @@ abstract class ContentHandler {
* (and only when) $wgActions[$action] === true. This allows subclasses
* to override the default action handlers.
*
* @stable for overriding
* @since 1.21
*
* @return array An array mapping action names (typically "view", "edit", "history" etc.) to
@ -594,7 +610,10 @@ abstract class ContentHandler {
/**
* Get an appropriate SlotDiffRenderer for this content model.
*
* @stable for overriding
* @since 1.32
*
* @param IContextSource $context
* @param array $options of the slot diff renderer (optional)
* @return SlotDiffRenderer
@ -631,8 +650,11 @@ abstract class ContentHandler {
/**
* Return the SlotDiffRenderer appropriate for this content handler.
* @stable for overriding
*
* @param IContextSource $context
* @param array $options
*
* @return SlotDiffRenderer
*/
protected function getSlotDiffRendererWithOptions( IContextSource $context, $options = [] ) {
@ -681,6 +703,7 @@ abstract class ContentHandler {
* Also note that the page language may or may not depend on the actual content of the page,
* that is, this method may load the content in order to determine the language.
*
* @stable for overriding
* @since 1.21
*
* @param Title $title The page to determine the language for.
@ -721,6 +744,7 @@ abstract class ContentHandler {
* Also note that the page language may or may not depend on the actual content of the page,
* that is, this method may load the content in order to determine the language.
*
* @stable for overriding
* @since 1.21
*
* @param Title $title The page to determine the language for.
@ -756,6 +780,8 @@ abstract class ContentHandler {
* @note this calls the ContentHandlerCanBeUsedOn hook which may be used to override which
* content model can be used where.
*
* @stable for overriding
*
* @see SlotRoleHandler::isAllowedModel
*
* @param Title $title The page's title.
@ -773,6 +799,7 @@ abstract class ContentHandler {
/**
* Returns the name of the diff engine to use.
*
* @stable for overriding
* @since 1.21
*
* @return string
@ -787,6 +814,7 @@ abstract class ContentHandler {
*
* This default implementation always returns false.
*
* @stable for overriding
* @since 1.21
*
* @param Content $oldContent The page's previous content.
@ -812,6 +840,7 @@ abstract class ContentHandler {
/**
* Return type of change if one exists for the given edit.
*
* @stable for overriding
* @since 1.31
*
* @param Content|null $oldContent The previous text of the page.
@ -879,6 +908,7 @@ abstract class ContentHandler {
/**
* Return an applicable auto-summary if one exists for the given edit.
*
* @stable for overriding
* @since 1.21
*
* @param Content|null $oldContent The previous text of the page.
@ -962,6 +992,7 @@ abstract class ContentHandler {
/**
* Return an applicable tag if one exists for the given edit or return null.
*
* @stable for overriding
* @since 1.31
*
* @param Content|null $oldContent The previous text of the page.
@ -998,6 +1029,7 @@ abstract class ContentHandler {
/**
* Auto-generates a deletion reason
*
* @stable for overriding
* @since 1.21
*
* @param Title $title The page's title
@ -1113,6 +1145,7 @@ abstract class ContentHandler {
* between $undo and $undoafter. Revisions must belong to the same page,
* must exist and must not be deleted.
*
* @stable for overriding
* @since 1.21
* @since 1.32 accepts Content objects for all parameters instead of Revision objects.
* Passing Revision objects is deprecated.
@ -1191,6 +1224,7 @@ abstract class ContentHandler {
* Returns true for content models that support caching using the
* ParserCache mechanism. See WikiPage::shouldCheckParserCache().
*
* @stable for overriding
* @since 1.21
*
* @return bool Always false.
@ -1206,6 +1240,8 @@ abstract class ContentHandler {
* Content models that return true here should also implement
* Content::getSection, Content::replaceSection, etc. to handle sections..
*
* @stable for overriding
*
* @return bool Always false.
*/
public function supportsSections() {
@ -1216,6 +1252,8 @@ abstract class ContentHandler {
* Returns true if this content model supports categories.
* The default implementation returns true.
*
* @stable for overriding
*
* @return bool Always true.
*/
public function supportsCategories() {
@ -1229,6 +1267,8 @@ abstract class ContentHandler {
* Content models that return true here should also implement
* ContentHandler::makeRedirectContent to return a Content object.
*
* @stable for overriding
*
* @return bool Always false.
*/
public function supportsRedirects() {
@ -1238,6 +1278,8 @@ abstract class ContentHandler {
/**
* Return true if this content model supports direct editing, such as via EditPage.
*
* @stable for overriding
*
* @return bool Default is false, and true for TextContent and it's derivatives.
*/
public function supportsDirectEditing() {
@ -1247,6 +1289,8 @@ abstract class ContentHandler {
/**
* Whether or not this content model supports direct editing via ApiEditPage
*
* @stable for overriding
*
* @return bool Default is false, and true for TextContent and derivatives.
*/
public function supportsDirectApiEditing() {
@ -1259,6 +1303,8 @@ abstract class ContentHandler {
* @todo Expose title, redirect, namespace, text, source_text, text_bytes
* field mappings here. (see T142670 and T143409)
*
* @stable for overriding
*
* @param SearchEngine $engine
* @return SearchIndexField[] List of fields this content handler can provide.
* @since 1.28
@ -1314,6 +1360,8 @@ abstract class ContentHandler {
* as representation of this document.
* Overriding class should call parent function or take care of calling
* the SearchDataForIndex hook.
* @stable for overriding
*
* @param WikiPage $page Page to index
* @param ParserOutput $output
* @param SearchEngine $engine Search engine for which we are indexing
@ -1353,6 +1401,8 @@ abstract class ContentHandler {
*
* Specific content handlers may override it if they need different content handling.
*
* @stable for overriding
*
* @param WikiPage $page
* @param ParserCache|null $cache
* @return ParserOutput
@ -1414,6 +1464,8 @@ abstract class ContentHandler {
* of $content. This allows existing ParserOutput objects to be re-used, while avoiding
* creating a ParserOutput when none is needed.
*
* @stable for overriding
*
* @param Title $title The title of the page to supply the updates for
* @param Content $content The content to generate data updates for.
* @param string $role The role (slot) in which the content is being used. Which updates
@ -1452,6 +1504,8 @@ abstract class ContentHandler {
* @note Implementations should not rely on the page's current content, but rather the current
* state of the secondary data store.
*
* @stable for overriding
*
* @param Title $title The title of the page to supply the updates for
* @param string $role The role (slot) in which the content is being used. Which updates
* are performed should generally not depend on the role the content has, but the

View file

@ -33,6 +33,7 @@ use MediaWiki\MediaWikiServices;
* TextContent instances are immutable
*
* @newable
* @stable for subclassing
* @ingroup Content
*/
class TextContent extends AbstractContent {
@ -74,6 +75,13 @@ class TextContent extends AbstractContent {
return $this; # NOTE: this is ok since TextContent are immutable.
}
/**
* @stable for overriding
*
* @param int $maxlength
*
* @return string
*/
public function getTextForSummary( $maxlength = 250 ) {
$text = $this->getText();
@ -86,6 +94,8 @@ class TextContent extends AbstractContent {
/**
* Returns the text's size in bytes.
*
* @stable for overriding
*
* @return int
*/
public function getSize() {
@ -98,6 +108,8 @@ class TextContent extends AbstractContent {
* Returns true if this content is not a redirect, and $wgArticleCountMethod
* is "any".
*
* @stable for overriding
*
* @param bool|null $hasLinks If it is known whether this content contains links,
* provide this information here, to avoid redundant parsing to find out.
*
@ -132,6 +144,9 @@ class TextContent extends AbstractContent {
* Returns the text represented by this Content object, as a string.
*
* @since 1.33
* @note This method should not be overwritten by subclasses. If a subclass find itself in
* need to override this method, it should probably not be based on TextContent, but
* should rather extend AbstractContent instead.
*
* @return string The raw text.
*/
@ -142,6 +157,8 @@ class TextContent extends AbstractContent {
/**
* Returns the text represented by this Content object, as a string.
*
* @stable for overriding
*
* @return string The raw text.
*/
public function getTextForSearchIndex() {
@ -152,6 +169,8 @@ class TextContent extends AbstractContent {
* Returns attempts to convert this content object to wikitext,
* and then returns the text string. The conversion may be lossy.
*
* @stable for overriding
*
* @note this allows any text-based content to be transcluded as if it was wikitext.
*
* @return string|bool The raw text, or false if the conversion failed.
@ -191,6 +210,8 @@ class TextContent extends AbstractContent {
* At a minimum, subclasses should make sure to call TextContent::normalizeLineEndings()
* either directly or part of Parser::preSaveTransform().
*
* @stable for overriding
*
* @param Title $title
* @param User $user
* @param ParserOptions $popts
@ -207,6 +228,7 @@ class TextContent extends AbstractContent {
/**
* Diff this content object with another content object.
*
* @stable for overriding
* @since 1.21
*
* @param Content $that The other content object to compare this content object to.
@ -249,6 +271,8 @@ class TextContent extends AbstractContent {
* Subclasses may override this to provide custom content processing.
* For custom HTML generation alone, it is sufficient to override getHtml().
*
* @stable for overriding
*
* @param Title $title Context title for parsing
* @param int $revId Revision ID (for {{REVISIONID}})
* @param ParserOptions $options
@ -284,6 +308,8 @@ class TextContent extends AbstractContent {
* If further information is to be derived from the content (such as
* categories), the fillParserOutput() method can be overridden instead.
*
* @stable for overriding
*
* @return string An HTML representation of the content
*/
protected function getHtml() {
@ -299,6 +325,8 @@ class TextContent extends AbstractContent {
* This implementation provides lossless conversion between content models based
* on TextContent.
*
* @stable for overriding
*
* @param string $toModel The desired content model, use the CONTENT_MODEL_XXX flags.
* @param string $lossy Flag, set to "lossy" to allow lossy conversion. If lossy conversion is not
* allowed, full round-trip conversion is expected to work without losing information.