Yurik has uploaded a new change for review.
https://gerrit.wikimedia.org/r/258196
Change subject: Allow JSON values to be included in the API results
......................................................................
Allow JSON values to be included in the API results
JSON value is added with
$this->getResult()->addValue( null, 'graph', $data, ApiResult::JSON_VALUE );
JSON formatter will add the value as a subtree:
{
"graph": {
"_1": 1,
"_type": 2,
"version": 2
}
}
XML formatter will output content:
<api>
<graph xml:space="preserve">{"_1":1,"_type":2,"version":2}</graph>
</api>
Bug: T120380
Change-Id: I7bd8646da281f4cbc320b1e77f5285abc3254ae4
---
M includes/api/ApiFormatJson.php
M includes/api/ApiResult.php
2 files changed, 34 insertions(+), 8 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/96/258196/1
diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php
index a319be3..8b7a72e 100644
--- a/includes/api/ApiFormatJson.php
+++ b/includes/api/ApiFormatJson.php
@@ -78,7 +78,7 @@
$opt |= $params['utf8'] ?
FormatJson::ALL_OK : FormatJson::XMLMETA_OK;
$transform = array(
'BC' => array(),
- 'Types' => array(
'AssocAsObject' => true ),
+ 'Types' => array(
'AssocAsObject' => true, 'JsonAsObject' => true ),
'Strip' => 'all',
);
break;
@@ -87,7 +87,7 @@
case 'latest':
$opt |= $params['ascii'] ?
FormatJson::XMLMETA_OK : FormatJson::ALL_OK;
$transform = array(
- 'Types' => array(
'AssocAsObject' => true ),
+ 'Types' => array(
'AssocAsObject' => true, 'JsonAsObject' => true ),
'Strip' => 'all',
);
break;
diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php
index e28cb82..3a6bdbb 100644
--- a/includes/api/ApiResult.php
+++ b/includes/api/ApiResult.php
@@ -64,6 +64,12 @@
const NO_VALIDATE = 12;
/**
+ * For addValue(), setValue() and similar functions, treat data as a
single JSON value.
+ * @since 1.26
+ */
+ const JSON_VALUE = 16;
+
+ /**
* Key for the 'indexed tag name' metadata item. Value is string.
* @since 1.25
*/
@@ -288,7 +294,7 @@
*/
public static function setValue( array &$arr, $name, $value, $flags = 0
) {
if ( ( $flags & ApiResult::NO_VALIDATE ) !==
ApiResult::NO_VALIDATE ) {
- $value = self::validateValue( $value );
+ $value = self::validateValue( $value, $flags );
}
if ( $name === null ) {
@@ -327,10 +333,23 @@
/**
* Validate a value for addition to the result
* @param mixed $value
+ * @param int $flags Zero or more OR-ed flags. For now only handles
JSON_VALUE
* @return array|mixed|string
*/
- private static function validateValue( $value ) {
+ private static function validateValue( $value, $flags = 0 ) {
global $wgContLang;
+
+ if ( $flags & ApiResult::JSON_VALUE ) {
+ // Wrap json value and cache it for XML formatter and
size check
+ $json = FormatJson::encode( $value, false,
FormatJson::ALL_OK );
+ if ( $json === false ) {
+ throw new InvalidArgumentException( "Cannot
encode value as JSON for ApiResult" );
+ }
+ // Cache string for XML formatter and size check and
skip all further value validation
+ $result = array( self::META_TYPE => 'json', '_value' =>
$value );
+ self::setContentValue( $result, '*', $json );
+ return $result;
+ }
if ( is_object( $value ) ) {
// Note we use is_callable() here instead of instanceof
because
@@ -404,7 +423,7 @@
if ( $this->checkingSize && !( $flags &
ApiResult::NO_SIZE_CHECK ) ) {
// self::valueSize needs the validated value. Then flag
// to not re-validate later.
- $value = self::validateValue( $value );
+ $value = self::validateValue( $value, $flags );
$flags |= ApiResult::NO_VALIDATE;
$newsize = $this->size + self::valueSize( $value );
@@ -939,6 +958,9 @@
// Apply transformation
switch ( $type ) {
+ case 'json':
+ return empty(
$transformTypes['JsonAsObject'] ) ? (object)$data : $metadata['_value'];
+
case 'assoc':
$metadata[self::META_TYPE] = 'assoc';
$data += $keepMetadata;
@@ -1089,9 +1111,13 @@
private static function valueSize( $value ) {
$s = 0;
if ( is_array( $value ) ) {
- foreach ( $value as $k => $v ) {
- if ( !self::isMetadataKey( $s ) ) {
- $s += self::valueSize( $v );
+ if ( $value[self::META_TYPE] === 'json' ) {
+ $s = strlen( $value['*'] );
+ } else {
+ foreach ( $value as $k => $v ) {
+ if ( !self::isMetadataKey( $s ) ) {
+ $s += self::valueSize( $v );
+ }
}
}
} elseif ( is_scalar( $value ) ) {
--
To view, visit https://gerrit.wikimedia.org/r/258196
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7bd8646da281f4cbc320b1e77f5285abc3254ae4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Yurik <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits