// the old way
ApiResult::setContentValue( $retval, 'wikitext', $wikitext );
} else {
+ $p_output = $wgParser->getOutput();
if ( isset( $prop['categories'] ) ) {
- $categories = $wgParser->getOutput()->getCategories();
+ $categories = $p_output->getCategories();
if ( $categories ) {
$categories_result = array();
foreach ( $categories as $category => $sortkey ) {
}
}
if ( isset( $prop['properties'] ) ) {
- $properties = $wgParser->getOutput()->getProperties();
+ $properties = $p_output->getProperties();
if ( $properties ) {
ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
ApiResult::setIndexedTagName( $properties, 'property' );
if ( isset( $prop['wikitext'] ) ) {
$retval['wikitext'] = $wikitext;
}
+ if ( isset( $prop['modules'] ) ) {
+ $retval['modules'] = array_values( array_unique( $p_output->getModules() ) );
+ $retval['modulescripts'] = array_values( array_unique( $p_output->getModuleScripts() ) );
+ $retval['modulestyles'] = array_values( array_unique( $p_output->getModuleStyles() ) );
+ }
+ if ( isset( $prop['jsconfigvars'] ) ) {
+ $retval['jsconfigvars'] =
+ ApiResult::addMetadataToResultVars( $p_output->getJsConfigVars() );
+ }
+ if ( isset( $prop['encodedjsconfigvars'] ) ) {
+ $retval['encodedjsconfigvars'] = FormatJson::encode(
+ $p_output->getJsConfigVars(), false, FormatJson::ALL_OK
+ );
+ $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
+ }
+ if ( isset( $prop['modules'] ) &&
+ !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
+ $this->setWarning( "Property 'modules' was set but not 'jsconfigvars' " .
+ "or 'encodedjsconfigvars'. Configuration variables are necessary " .
+ "for proper module usage.");
+ }
}
}
ApiResult::setSubelementsList( $retval, array( 'wikitext', 'parsetree' ) );
'properties',
'volatile',
'ttl',
+ 'modules',
+ 'jsconfigvars',
+ 'encodedjsconfigvars',
'parsetree',
),
ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_HELP_MSG_PER_VALUE => array(),
),
'includecomments' => false,
'generatexml' => array(
if ( isset( $params['section'] ) ) {
$this->section = $params['section'];
if ( !preg_match( '/^((T-)?\d+|new)$/', $this->section ) ) {
- $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
+ $this->dieUsage(
+ "The section parameter must be a valid section id or 'new'", "invalidsection"
+ );
}
} else {
$this->section = false;
if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
if ( $this->section === 'new' ) {
- $this->dieUsage( 'section=new cannot be combined with oldid, pageid or page parameters. Please use text', 'params' );
+ $this->dieUsage(
+ 'section=new cannot be combined with oldid, pageid or page parameters. ' .
+ 'Please use text', 'params'
+ );
}
if ( !is_null( $oldid ) ) {
// Don't use the parser cache
}
if ( isset( $prop['jsconfigvars'] ) ) {
- $result_array['jsconfigvars'] = $this->formatJsConfigVars( $p_result->getJsConfigVars() );
+ $result_array['jsconfigvars'] =
+ ApiResult::addMetadataToResultVars( $p_result->getJsConfigVars() );
}
if ( isset( $prop['encodedjsconfigvars'] ) ) {
$result_array[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
}
+ if ( isset( $prop['modules'] ) &&
+ !isset( $prop['jsconfigvars'] ) && !isset( $prop['encodedjsconfigvars'] ) ) {
+ $this->setWarning( "Property 'modules' was set but not 'jsconfigvars' " .
+ "or 'encodedjsconfigvars'. Configuration variables are necessary " .
+ "for proper module usage.");
+ }
+
if ( isset( $prop['indicators'] ) ) {
$result_array['indicators'] = (array)$p_result->getIndicators();
ApiResult::setArrayType( $result_array['indicators'], 'BCkvp', 'name' );
$sectionTitle = !is_null( $params['sectiontitle'] ) ? $params['sectiontitle'] : '';
if ( $this->section === 'new' && ( $sectionTitle === '' || $summary === '' ) ) {
- if( $sectionTitle !== '' ) {
+ if ( $sectionTitle !== '' ) {
$summary = $params['sectiontitle'];
}
if ( $summary !== '' ) {
- $summary = wfMessage( 'newsectionsummary' )->rawParams( $wgParser->stripSectionName( $summary ) )
- ->inContentLanguage()->text();
+ $summary = wfMessage( 'newsectionsummary' )
+ ->rawParams( $wgParser->stripSectionName( $summary ) )
+ ->inContentLanguage()->text();
}
}
return Linker::formatComment( $summary, $title, $this->section === 'new' );
return $result;
}
- private function formatJsConfigVars( $vars, $forceHash = true ) {
- // Process subarrays and determine if this is a JS [] or {}
- $hash = $forceHash;
- $maxKey = -1;
- $bools = array();
- foreach ( $vars as $k => $v ) {
- if ( is_array( $v ) || is_object( $v ) ) {
- $vars[$k] = $this->formatJsConfigVars( (array)$v, false );
- } elseif ( is_bool( $v ) ) {
- // Better here to use real bools even in BC formats
- $bools[] = $k;
- }
- if ( is_string( $k ) ) {
- $hash = true;
- } elseif ( $k > $maxKey ) {
- $maxKey = $k;
- }
- }
- if ( !$hash && $maxKey !== count( $vars ) - 1 ) {
- $hash = true;
- }
-
- // Get the list of keys we actually care about. Unfortunately, we can't support
- // certain keys that conflict with ApiResult metadata.
- $keys = array_diff( array_keys( $vars ), array(
- ApiResult::META_TYPE, ApiResult::META_PRESERVE_KEYS, ApiResult::META_KVP_KEY_NAME,
- ApiResult::META_INDEXED_TAG_NAME, ApiResult::META_BC_BOOLS
- ) );
-
- // Set metadata appropriately
- if ( $hash ) {
- return array(
- ApiResult::META_TYPE => 'kvp',
- ApiResult::META_KVP_KEY_NAME => 'key',
- ApiResult::META_PRESERVE_KEYS => $keys,
- ApiResult::META_BC_BOOLS => $bools,
- ApiResult::META_INDEXED_TAG_NAME => 'var',
- ) + $vars;
- } else {
- return array(
- ApiResult::META_TYPE => 'array',
- ApiResult::META_BC_BOOLS => $bools,
- ApiResult::META_INDEXED_TAG_NAME => 'value',
- ) + $vars;
- }
- }
-
private function setIndexedTagNames( &$array, $mapping ) {
foreach ( $mapping as $key => $name ) {
if ( isset( $array[$key] ) ) {
$arr[$name] += $value;
} else {
$keys = join( ', ', array_keys( $conflicts ) );
- throw new RuntimeException( "Conflicting keys ($keys) when attempting to merge element $name" );
+ throw new RuntimeException(
+ "Conflicting keys ($keys) when attempting to merge element $name"
+ );
}
} else {
- throw new RuntimeException( "Attempting to add element $name=$value, existing value is {$arr[$name]}" );
+ throw new RuntimeException(
+ "Attempting to add element $name=$value, existing value is {$arr[$name]}"
+ );
}
}
* @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
*/
public static function setArrayType( array &$arr, $type, $kvpKeyName = null ) {
- if ( !in_array( $type, array( 'default', 'array', 'assoc', 'kvp', 'BCarray', 'BCassoc', 'BCkvp' ), true ) ) {
+ if ( !in_array( $type, array(
+ 'default', 'array', 'assoc', 'kvp', 'BCarray', 'BCassoc', 'BCkvp'
+ ), true ) ) {
throw new InvalidArgumentException( 'Bad type' );
}
$arr[self::META_TYPE] = $type;
/**
* Get the 'real' size of a result item. This means the strlen() of the item,
* or the sum of the strlen()s of the elements if the item is an array.
- * @note Once the deprecated public self::size is removed, we can rename this back to a less awkward name.
+ * @note Once the deprecated public self::size is removed, we can rename
+ * this back to a less awkward name.
* @param mixed $value
* @return int
*/
return $ret;
}
+ /**
+ * Add the correct metadata to an array of vars we want to export through
+ * the API.
+ *
+ * @param array $vars
+ * @param boolean $forceHash
+ * @return array
+ */
+ public static function addMetadataToResultVars( $vars, $forceHash = true ) {
+ // Process subarrays and determine if this is a JS [] or {}
+ $hash = $forceHash;
+ $maxKey = -1;
+ $bools = array();
+ foreach ( $vars as $k => $v ) {
+ if ( is_array( $v ) || is_object( $v ) ) {
+ $vars[$k] = ApiResult::addMetadataToResultVars( (array)$v, is_object( $v ) );
+ } elseif ( is_bool( $v ) ) {
+ // Better here to use real bools even in BC formats
+ $bools[] = $k;
+ }
+ if ( is_string( $k ) ) {
+ $hash = true;
+ } elseif ( $k > $maxKey ) {
+ $maxKey = $k;
+ }
+ }
+ if ( !$hash && $maxKey !== count( $vars ) - 1 ) {
+ $hash = true;
+ }
+
+ // Set metadata appropriately
+ if ( $hash ) {
+ // Get the list of keys we actually care about. Unfortunately, we can't support
+ // certain keys that conflict with ApiResult metadata.
+ $keys = array_diff( array_keys( $vars ), array(
+ ApiResult::META_TYPE, ApiResult::META_PRESERVE_KEYS, ApiResult::META_KVP_KEY_NAME,
+ ApiResult::META_INDEXED_TAG_NAME, ApiResult::META_BC_BOOLS
+ ) );
+
+ return array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => $keys,
+ ApiResult::META_BC_BOOLS => $bools,
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ ) + $vars;
+ } else {
+ return array(
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_BC_BOOLS => $bools,
+ ApiResult::META_INDEXED_TAG_NAME => 'value',
+ ) + $vars;
+ }
+ }
+
/**@}*/
/************************************************************************//**
"apihelp-expandtemplates-param-title": "Title of page.",
"apihelp-expandtemplates-param-text": "Wikitext to convert.",
"apihelp-expandtemplates-param-revid": "Revision ID, for <nowiki>{{REVISIONID}}</nowiki> and similar variables.",
- "apihelp-expandtemplates-param-prop": "Which pieces of information to get:\n;wikitext:The expanded wikitext.\n;categories:Any categories present in the input that are not represented in the wikitext output.\n;properties:Page properties defined by expanded magic words in the wikitext.\n;volatile:Whether the output is volatile and should not be reused elsewhere within the page.\n;ttl:The maximum time after which caches of the result should be invalidated.\n;parsetree:The XML parse tree of the input.\nNote that if no values are selected, the result will contain the wikitext, but the output will be in a deprecated format.",
+ "apihelp-expandtemplates-param-prop": "Which pieces of information to get.\n\nNote that if no values are selected, the result will contain the wikitext, but the output will be in a deprecated format.",
+ "apihelp-expandtemplates-paramvalue-prop-wikitext": "The expanded wikitext.",
+ "apihelp-expandtemplates-paramvalue-prop-categories": "Any categories present in the input that are not represented in the wikitext output.",
+ "apihelp-expandtemplates-paramvalue-prop-properties": "Page properties defined by expanded magic words in the wikitext.",
+ "apihelp-expandtemplates-paramvalue-prop-volatile": "Whether the output is volatile and should not be reused elsewhere within the page.",
+ "apihelp-expandtemplates-paramvalue-prop-ttl": "The maximum time after which caches of the result should be invalidated.",
+ "apihelp-expandtemplates-paramvalue-prop-modules": "Any ResourceLoader modules that parser functions have requested be added to the output. Either <kbd>jsconfigvars</kbd> or <kbd>encodedjsconfigvars</kbd> must be requested jointly with <kbd>modules</kbd>.",
+ "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "Gives the JavaScript configuration variables specific to the page.",
+ "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "Gives the JavaScript configuration variables specific to the page as a JSON string.",
+ "apihelp-expandtemplates-paramvalue-prop-parsetree": "The XML parse tree of the input.",
"apihelp-expandtemplates-param-includecomments": "Whether to include HTML comments in the output.",
"apihelp-expandtemplates-param-generatexml": "Generate XML parse tree (replaced by $1prop=parsetree).",
"apihelp-expandtemplates-example-simple": "Expand the wikitext <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
"apihelp-parse-paramvalue-prop-displaytitle": "Adds the title of the parsed wikitext.",
"apihelp-parse-paramvalue-prop-headitems": "Gives items to put in the <code><head></code> of the page.",
"apihelp-parse-paramvalue-prop-headhtml": "Gives parsed <code><head></code> of the page.",
- "apihelp-parse-paramvalue-prop-modules": "Gives the ResourceLoader modules used on the page.",
+ "apihelp-parse-paramvalue-prop-modules": "Gives the ResourceLoader modules used on the page. Either <kbd>jsconfigvars</kbd> or <kbd>encodedjsconfigvars</kbd> must be requested jointly with <kbd>modules</kbd>.",
"apihelp-parse-paramvalue-prop-jsconfigvars": "Gives the JavaScript configuration variables specific to the page.",
"apihelp-parse-paramvalue-prop-encodedjsconfigvars": "Gives the JavaScript configuration variables specific to the page as a JSON string.",
"apihelp-parse-paramvalue-prop-indicators": "Gives the HTML of page status indicators used on the page.",
"apihelp-expandtemplates-param-title": "{{doc-apihelp-param|expandtemplates|title}}",
"apihelp-expandtemplates-param-text": "{{doc-apihelp-param|expandtemplates|text}}",
"apihelp-expandtemplates-param-revid": "{{doc-apihelp-param|expandtemplates|revid}}\n{{doc-important|Do not translate <code><<nowiki />nowiki>{{<nowiki />REVISIONID}}<<nowiki />/nowiki></code>}}",
- "apihelp-expandtemplates-param-prop": "{{doc-apihelp-param|expandtemplates|prop}}",
+ "apihelp-expandtemplates-param-prop": "{{doc-apihelp-param|expandtemplates|prop|paramvalues=1}}",
+ "apihelp-expandtemplates-paramvalue-prop-wikitext": "{{doc-apihelp-paramvalue|expandtemplates|prop|wikitext}}",
+ "apihelp-expandtemplates-paramvalue-prop-categories": "{{doc-apihelp-paramvalue|expandtemplates|prop|categories}}",
+ "apihelp-expandtemplates-paramvalue-prop-properties": "{{doc-apihelp-paramvalue|expandtemplates|prop|properties}}",
+ "apihelp-expandtemplates-paramvalue-prop-volatile": "{{doc-apihelp-paramvalue|expandtemplates|prop|volatile}}",
+ "apihelp-expandtemplates-paramvalue-prop-ttl": "{{doc-apihelp-paramvalue|expandtemplates|prop|ttl}}",
+ "apihelp-expandtemplates-paramvalue-prop-modules": "{{doc-apihelp-paramvalue|expandtemplates|prop|modules}}",
+ "apihelp-expandtemplates-paramvalue-prop-jsconfigvars": "{{doc-apihelp-paramvalue|expandtemplates|prop|jsconfigvars}}",
+ "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "{{doc-apihelp-paramvalue|expandtemplates|prop|encodedjsconfigvars}}",
+ "apihelp-expandtemplates-paramvalue-prop-parsetree": "{{doc-apihelp-paramvalue|expandtemplates|prop|parsetree}}",
"apihelp-expandtemplates-param-includecomments": "{{doc-apihelp-param|expandtemplates|includecomments}}",
"apihelp-expandtemplates-param-generatexml": "{{doc-apihelp-param|expandtemplates|generatexml}}",
"apihelp-expandtemplates-example-simple": "{{doc-apihelp-example|expandtemplates}}",
$data[ApiResult::META_CONTENT] = 'bar';
}
+ /**
+ * @covers ApiResult
+ */
+ public function testAddMetadataToResultVars() {
+ $arr = array(
+ 'a' => "foo",
+ 'b' => false,
+ 'c' => 10,
+ 'sequential_numeric_keys' => array( 'a', 'b', 'c' ),
+ 'non_sequential_numeric_keys' => array( 'a', 'b', 4 => 'c' ),
+ 'string_keys' => array(
+ 'one' => 1,
+ 'two' => 2
+ ),
+ 'object_sequential_keys' => (object)array( 'a', 'b', 'c' ),
+ '_type' => "should be overwritten in result",
+ );
+ $this->assertSame( array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array(
+ 'a', 'b', 'c',
+ 'sequential_numeric_keys', 'non_sequential_numeric_keys',
+ 'string_keys', 'object_sequential_keys'
+ ),
+ ApiResult::META_BC_BOOLS => array( 'b' ),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 'a' => "foo",
+ 'b' => false,
+ 'c' => 10,
+ 'sequential_numeric_keys' => array(
+ ApiResult::META_TYPE => 'array',
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'value',
+ 0 => 'a',
+ 1 => 'b',
+ 2 => 'c',
+ ),
+ 'non_sequential_numeric_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 0, 1, 4 ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 0 => 'a',
+ 1 => 'b',
+ 4 => 'c',
+ ),
+ 'string_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 'one', 'two' ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 'one' => 1,
+ 'two' => 2,
+ ),
+ 'object_sequential_keys' => array(
+ ApiResult::META_TYPE => 'kvp',
+ ApiResult::META_KVP_KEY_NAME => 'key',
+ ApiResult::META_PRESERVE_KEYS => array( 0, 1, 2 ),
+ ApiResult::META_BC_BOOLS => array(),
+ ApiResult::META_INDEXED_TAG_NAME => 'var',
+ 0 => 'a',
+ 1 => 'b',
+ 2 => 'c',
+ ),
+ ), ApiResult::addMetadataToResultVars( $arr ) );
+ }
+
/**
* @covers ApiResult
*/