Legoktm has uploaded a new change for review.
https://gerrit.wikimedia.org/r/307017
Change subject: [WIP] API: Output structured content representation if requested
......................................................................
[WIP] API: Output structured content representation if requested
This adds a prop=structuredcontent, which will output a structured
representation of the Content if the handler supports it.
ContentHandlers must override ContentHandler::formatForApiOutput(), and
return information structured in a format compatible with the API (can't
have any of the magic underscore-prefixed keys).
The TextContent implementation returns the raw underlying text, and
JsonContent will return the parsed JSON structure.
Bug: T143967
Change-Id: I3d18bfb017feed69ee9f08db136dab39382e4171
---
M includes/api/ApiQueryRevisionsBase.php
M includes/content/ContentHandler.php
M includes/content/JsonContentHandler.php
M includes/content/TextContentHandler.php
4 files changed, 83 insertions(+), 6 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/17/307017/1
diff --git a/includes/api/ApiQueryRevisionsBase.php
b/includes/api/ApiQueryRevisionsBase.php
index 266d699..f7767cb 100644
--- a/includes/api/ApiQueryRevisionsBase.php
+++ b/includes/api/ApiQueryRevisionsBase.php
@@ -37,7 +37,8 @@
protected $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
$fld_size = false, $fld_sha1 = false, $fld_comment = false,
$fld_parsedcomment = false, $fld_user = false, $fld_userid =
false,
- $fld_content = false, $fld_tags = false, $fld_contentmodel =
false, $fld_parsetree = false;
+ $fld_content = false, $fld_tags = false, $fld_contentmodel =
false, $fld_parsetree = false,
+ $fld_structuredcontent = false;
public function execute() {
$this->run();
@@ -101,11 +102,18 @@
$this->fld_size = isset( $prop['size'] );
$this->fld_sha1 = isset( $prop['sha1'] );
$this->fld_content = isset( $prop['content'] );
+ $this->fld_structuredcontent = isset(
$prop['structuredcontent'] );
$this->fld_contentmodel = isset( $prop['contentmodel'] );
$this->fld_userid = isset( $prop['userid'] );
$this->fld_user = isset( $prop['user'] );
$this->fld_tags = isset( $prop['tags'] );
$this->fld_parsetree = isset( $prop['parsetree'] );
+
+ if ( $this->fld_content && $this->fld_structuredcontent ) {
+ $p = $this->getModulePrefix();
+ $this->dieUsage( "{$p}prop cannot contain both the
content and structuredcontent properties.",
+ 'invalidpropmix' );
+ }
if ( !empty( $params['contentformat'] ) ) {
$this->contentFormat = $params['contentformat'];
@@ -113,8 +121,8 @@
$this->limit = $params['limit'];
- $this->fetchContent = $this->fld_content || !is_null(
$this->diffto )
- || !is_null( $this->difftotext ) ||
$this->fld_parsetree;
+ $this->fetchContent = $this->fld_content ||
$this->fld_structuredcontent
+ || !is_null( $this->diffto ) || !is_null(
$this->difftotext ) || $this->fld_parsetree;
$smallLimit = false;
if ( $this->fetchContent ) {
@@ -301,7 +309,7 @@
}
}
- if ( $this->fld_content && $content ) {
+ if ( ( $this->fld_content || $this->fld_structuredcontent ) &&
$content ) {
$text = null;
if ( $this->expandTemplates && !$this->parseContent ) {
@@ -331,8 +339,8 @@
$text = $po->getText();
}
- if ( $text === null ) {
- $format = $this->contentFormat ?:
$content->getDefaultFormat();
+ $format = $this->contentFormat ?:
$content->getDefaultFormat();
+ if ( $text === null && $this->fld_content ) {
$model = $content->getModel();
if ( !$content->isSupportedFormat( $format ) ) {
@@ -350,8 +358,30 @@
}
}
+ if ( $this->fld_structuredcontent ) {
+ $handler = ContentHandler::getForContent(
$content );
+ // Yes this probably isn't text, but...
+ $text = $handler->formatForApiOutput( $content
);
+ if ( $text === false ) {
+ $model = $content->getModel();
+ $this->setWarning(
+ "The content model $model does
not support outputting structured content. "
+ . "Falling back to serialized
representation."
+ );
+ $text = $content->serialize( $format );
+ } else {
+ // Set the proper metadata so content
is represented properly regardless of
+ // output format. Also need to force it
to be an array...
+ if ( is_array( $text ) || $text
instanceof stdClass ) {
+ $text =
ApiResult::addMetadataToResultVars( (array)$text, is_object( $text ) );
+ }
+ }
+ }
+
if ( $text !== false ) {
ApiResult::setContentValue( $vals, 'content',
$text );
+
+
}
}
@@ -440,6 +470,7 @@
'comment',
'parsedcomment',
'content',
+ 'structuredcontent',
'tags',
'parsetree',
],
@@ -456,6 +487,7 @@
'comment' =>
'apihelp-query+revisions+base-paramvalue-prop-comment',
'parsedcomment' =>
'apihelp-query+revisions+base-paramvalue-prop-parsedcomment',
'content' =>
'apihelp-query+revisions+base-paramvalue-prop-content',
+ 'structuredcontent' =>
'apihelp-query+revisions+base-paramvalue-prop-structuredcontent',
'tags' =>
'apihelp-query+revisions+base-paramvalue-prop-tags',
'parsetree' => [
'apihelp-query+revisions+base-paramvalue-prop-parsetree',
CONTENT_MODEL_WIKITEXT ],
diff --git a/includes/content/ContentHandler.php
b/includes/content/ContentHandler.php
index 41fdef5..3c29280 100644
--- a/includes/content/ContentHandler.php
+++ b/includes/content/ContentHandler.php
@@ -1132,6 +1132,23 @@
}
/**
+ * Get a structured representation of the content suitable for
+ * API output. Note that some special keys are reserved by the API
+ * for internal metadata, see class constants on ApiResult for
+ * more details.
+ *
+ * The default implementation returns false, indicating that no
+ * alternative structured content is available.
+ *
+ * @since 1.28
+ * @param Content $content
+ * @return array|stdClass|string|bool
+ */
+ public function formatForApiOutput( Content $content ) {
+ return false;
+ }
+
+ /**
* Logs a deprecation warning, visible if $wgDevelopmentWarnings, but
only if
* self::$enableDeprecationWarnings is set to true.
*
diff --git a/includes/content/JsonContentHandler.php
b/includes/content/JsonContentHandler.php
index eb1c67d..039739a 100644
--- a/includes/content/JsonContentHandler.php
+++ b/includes/content/JsonContentHandler.php
@@ -39,4 +39,18 @@
protected function getContentClass() {
return JsonContent::class;
}
+
+ /**
+ * @param Content $content
+ * @throws InvalidArgumentException
+ * @return stdClass
+ */
+ public function formatForApiOutput( Content $content ) {
+ if ( !$content instanceof JsonContent ) {
+ throw new InvalidArgumentException(
+ 'Expected JsonContent class, got ' . get_class(
$content ) );
+ }
+
+ return $content->getData()->getValue();
+ }
}
diff --git a/includes/content/TextContentHandler.php
b/includes/content/TextContentHandler.php
index 09cdcee..2ecad62 100644
--- a/includes/content/TextContentHandler.php
+++ b/includes/content/TextContentHandler.php
@@ -158,4 +158,18 @@
return $fields;
}
+ /**
+ * @param Content $content
+ * @throws InvalidArgumentException
+ * @return string
+ */
+ public function formatForApiOutput( Content $content ) {
+ if ( !$content instanceof TextContent ) {
+ throw new InvalidArgumentException(
+ 'Expected TextContent class, got ' . get_class(
$content ) );
+ }
+
+ return $content->getNativeData();
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/307017
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3d18bfb017feed69ee9f08db136dab39382e4171
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Legoktm <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits