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

Reply via email to