as comma-separated lists.
* merge events use new-style formatting.
* delete/event and delete/revision events use new-style formatting.
+* The root node and various other nodes will now always be an object in formats
+ such as json that distinguish between arrays and objects.
+ * Except for action=opensearch where the spec requires an array.
=== Action API internal changes in 1.25 ===
* ApiHelp has been rewritten to support i18n and paginated HTML output.
metadata isn't set.
* (T35235) LogFormatter subclasses are now responsible for formatting log event
parameters for the API.
+* Many modules have changed result data formats. While this shouldn't affect
+ clients not using the experimental formatversion=2015, code using
+ ApiResult::getResultData() and not using ApiResult::transformForBC() may need
+ updating.
* The following methods have been deprecated and may be removed in a future
release:
* ApiBase::getDescription
}
$res['reason'] = $params['reason'];
- if ( $params['anononly'] ) {
- $res['anononly'] = '';
- }
- if ( $params['nocreate'] ) {
- $res['nocreate'] = '';
- }
- if ( $params['autoblock'] ) {
- $res['autoblock'] = '';
- }
- if ( $params['noemail'] ) {
- $res['noemail'] = '';
- }
- if ( $params['hidename'] ) {
- $res['hidename'] = '';
- }
- if ( $params['allowusertalk'] ) {
- $res['allowusertalk'] = '';
- }
- if ( $params['watchuser'] ) {
- $res['watchuser'] = '';
- }
+ $res['anononly'] = $params['anononly'];
+ $res['nocreate'] = $params['nocreate'];
+ $res['autoblock'] = $params['autoblock'];
+ $res['noemail'] = $params['noemail'];
+ $res['hidename'] = $params['hidename'];
+ $res['allowusertalk'] = $params['allowusertalk'];
+ $res['watchuser'] = $params['watchuser'];
$this->getResult()->addValue( null, $this->getModuleName(), $res );
}
ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
}
if ( $batchcomplete ) {
- $result->addValue( null, 'batchcomplete', '',
+ $result->addValue( null, 'batchcomplete', true,
ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
}
}
$this->dieStatus( $status );
case EditPage::AS_SUCCESS_NEW_ARTICLE:
- $r['new'] = '';
+ $r['new'] = true;
// fall-through
case EditPage::AS_SUCCESS_UPDATE:
$r['contentmodel'] = $titleObj->getContentModel();
$newRevId = $articleObject->getLatest();
if ( $newRevId == $oldRevId ) {
- $r['nochange'] = '';
+ $r['nochange'] = true;
} else {
$r['oldrevid'] = intval( $oldRevId );
$r['newrevid'] = intval( $newRevId );
$retval['parsetree'] = $xml;
} else {
// the old way
- $xml_result = array();
- ApiResult::setContentValue( $xml_result, 'xml', $xml );
- $result->addValue( null, 'parsetree', $xml_result );
+ $result->addValue( null, 'parsetree', $xml );
+ $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, array( 'parsetree' ) );
}
}
if ( isset( $prop['properties'] ) ) {
$properties = $wgParser->getOutput()->getProperties();
if ( $properties ) {
- $properties_result = array();
- foreach ( $properties as $name => $value ) {
- $entry = array();
- $entry['name'] = $name;
- ApiResult::setContentValue( $entry, 'value', $value );
- $properties_result[] = $entry;
- }
- ApiResult::setIndexedTagName( $properties_result, 'property' );
- $retval['properties'] = $properties_result;
+ ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
+ ApiResult::setIndexedTagName( $properties, 'property' );
+ $retval['properties'] = $properties;
}
}
- if ( isset( $prop['volatile'] ) && $frame->isVolatile() ) {
- $retval['volatile'] = '';
+ if ( isset( $prop['volatile'] ) ) {
+ $retval['volatile'] = $frame->isVolatile();
}
if ( isset( $prop['ttl'] ) && $frame->getTTL() !== null ) {
$retval['ttl'] = $frame->getTTL();
$v = $val;
}
if ( $flag !== null ) {
- $v[$flag] = '';
+ $v[$flag] = true;
}
$result[] = $v;
}
$r['id'] = $title->getArticleID();
ApiQueryBase::addTitleInfo( $r, $title );
if ( !$title->exists() ) {
- $r['missing'] = '';
+ $r['missing'] = true;
}
$file = wfFindFile( $title, array( 'latest' => true ) );
if ( $title === null ) {
# Invalid or non-importable title
$r['title'] = $pageInfo['title'];
- $r['invalid'] = '';
+ $r['invalid'] = true;
} else {
ApiQueryBase::addTitleInfo( $r, $title );
$r['revisions'] = intval( $successCount );
if ( !$status->isGood() ) {
$ret['warnings'] = $this->getErrorFormatter()->arrayFromStatus( $status, 'warning' );
}
- if ( $status->value !== null ) {
- $ret['success'] = '';
+ $ret['success'] = $status->value !== null;
+ if ( $ret['success'] ) {
$ret['logid'] = $status->value;
}
$result->addValue( null, $this->getModuleName(), $ret );
'reason' => $params['reason']
);
- if ( $fromTitle->exists() ) {
- //NOTE: we assume that if the old title exists, it's because it was re-created as
- // a redirect to the new title. This is not safe, but what we did before was
- // even worse: we just determined whether a redirect should have been created,
- // and reported that it was created if it should have, without any checks.
- // Also note that isRedirect() is unreliable because of bug 37209.
- $r['redirectcreated'] = '';
- }
+ //NOTE: we assume that if the old title exists, it's because it was re-created as
+ // a redirect to the new title. This is not safe, but what we did before was
+ // even worse: we just determined whether a redirect should have been created,
+ // and reported that it was created if it should have, without any checks.
+ // Also note that isRedirect() is unreliable because of bug 37209.
+ $r['redirectcreated'] = $fromTitle->exists();
- if ( $toTitleExists ) {
- $r['moveoverredirect'] = '';
- }
+ $r['moveoverredirect'] = $toTitleExists;
// Move the talk page
if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() ) {
if ( $status->isOK() ) {
$r['talkfrom'] = $fromTalk->getPrefixedText();
$r['talkto'] = $toTalk->getPrefixedText();
- if ( $toTalkExists ) {
- $r['talkmoveoverredirect'] = '';
- }
+ $r['talkmoveoverredirect'] = $toTalkExists;
} else {
// We're not gonna dieUsage() on failure, since we already changed something
$error = $this->getErrorFromStatus( $status );
switch ( $this->getFormat() ) {
case 'json':
// http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.1
+ $result->addArrayType( null, 'array' );
$result->addValue( null, 0, strval( $search ) );
$terms = array();
$descriptions = array();
$v = $val;
}
if ( $flag !== null ) {
- $v[$flag] = '';
+ $v[$flag] = true;
}
$result[] = $v;
}
$this->formatHelpMessages( $ret, 'description', $module->getFinalDescription() );
foreach ( $module->getHelpFlags() as $flag ) {
- $ret[$flag] = '';
+ $ret[$flag] = true;
}
$ret['helpurls'] = (array)$module->getHelpUrls();
$this->formatHelpMessages( $item, 'description', $paramDesc[$name], true );
}
- if ( !empty( $settings[ApiBase::PARAM_REQUIRED] ) ) {
- $item['required'] = '';
- }
+ $item['required'] = !empty( $settings[ApiBase::PARAM_REQUIRED] );
if ( !empty( $settings[ApiBase::PARAM_DEPRECATED] ) ) {
- $item['deprecated'] = '';
+ $item['deprecated'] = true;
}
if ( $name === 'token' && $module->needsToken() ) {
}
}
- if ( !empty( $settings[ApiBase::PARAM_ISMULTI] ) ) {
- $item['multi'] = '';
+ $item['multi'] = !empty( $settings[ApiBase::PARAM_ISMULTI] );
+ if ( $item['multi'] ) {
$item['limit'] = $this->getMain()->canApiHighLimits() ?
ApiBase::LIMIT_SML2 :
ApiBase::LIMIT_SML1;
}
if ( !empty( $settings[ApiBase::PARAM_ALLOW_DUPLICATES] ) ) {
- $item['allowsduplicates'] = '';
+ $item['allowsduplicates'] = true;
}
if ( isset( $settings[ApiBase::PARAM_TYPE] ) ) {
if ( $settings[ApiBase::PARAM_TYPE] === 'submodule' ) {
$item['type'] = $module->getModuleManager()->getNames( $name );
sort( $item['type'] );
- $item['submodules'] = '';
+ $item['submodules'] = true;
} else {
$item['type'] = $settings[ApiBase::PARAM_TYPE];
}
if ( $params['onlypst'] ) {
// Build a result and bail out
$result_array = array();
- $result_array['text'] = array();
- ApiResult::setContentValue( $result_array['text'], 'text', $this->pstContent->serialize( $format ) );
+ $result_array['text'] = $this->pstContent->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
if ( isset( $prop['wikitext'] ) ) {
- $result_array['wikitext'] = array();
- ApiResult::setContentValue( $result_array['wikitext'], 'wikitext', $this->content->serialize( $format ) );
+ $result_array['wikitext'] = $this->content->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
}
if ( !is_null( $params['summary'] ) ||
( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
) {
- $result_array['parsedsummary'] = array();
- ApiResult::setContentValue(
- $result_array['parsedsummary'],
- 'parsedsummary',
- $this->formatSummary( $titleObj, $params )
- );
+ $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
}
$result->addValue( null, $this->getModuleName(), $result_array );
}
if ( isset( $prop['text'] ) ) {
- $result_array['text'] = array();
- ApiResult::setContentValue( $result_array['text'], 'text', $p_result->getText() );
+ $result_array['text'] = $p_result->getText();
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
}
if ( !is_null( $params['summary'] ) ||
( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
) {
- $result_array['parsedsummary'] = array();
- ApiResult::setContentValue(
- $result_array['parsedsummary'],
- 'parsedsummary',
- $this->formatSummary( $titleObj, $params )
- );
+ $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
}
if ( isset( $prop['langlinks'] ) ) {
$result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
}
if ( isset( $prop['categorieshtml'] ) ) {
- $categoriesHtml = $this->categoriesHtml( $p_result->getCategories() );
- $result_array['categorieshtml'] = array();
- ApiResult::setContentValue( $result_array['categorieshtml'], 'categorieshtml', $categoriesHtml );
+ $result_array['categorieshtml'] = $this->categoriesHtml( $p_result->getCategories() );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
}
if ( isset( $prop['links'] ) ) {
$result_array['links'] = $this->formatLinks( $p_result->getLinks() );
}
if ( isset( $prop['headhtml'] ) ) {
- $result_array['headhtml'] = array();
- ApiResult::setContentValue(
- $result_array['headhtml'],
- 'headhtml',
- $context->getOutput()->headElement( $context->getSkin() )
- );
+ $result_array['headhtml'] = $context->getOutput()->headElement( $context->getSkin() );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
}
}
}
if ( isset( $prop['indicators'] ) ) {
- foreach ( $p_result->getIndicators() as $name => $content ) {
- $indicator = array( 'name' => $name );
- ApiResult::setContentValue( $indicator, 'content', $content );
- $result_array['indicators'][] = $indicator;
- }
+ $result_array['indicators'] = (array)$p_result->getIndicators();
+ ApiResult::setArrayType( $result_array['indicators'], 'BCkvp', 'name' );
}
if ( isset( $prop['iwlinks'] ) ) {
}
if ( isset( $prop['wikitext'] ) ) {
- $result_array['wikitext'] = array();
- ApiResult::setContentValue( $result_array['wikitext'], 'wikitext', $this->content->serialize( $format ) );
+ $result_array['wikitext'] = $this->content->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
if ( !is_null( $this->pstContent ) ) {
- $result_array['psttext'] = array();
- ApiResult::setContentValue( $result_array['psttext'], 'psttext', $this->pstContent->serialize( $format ) );
+ $result_array['psttext'] = $this->pstContent->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'psttext';
}
}
if ( isset( $prop['properties'] ) ) {
- $result_array['properties'] = $this->formatProperties( $p_result->getProperties() );
+ $result_array['properties'] = (array)$p_result->getProperties();
+ ApiResult::setArrayType( $result_array['properties'], 'BCkvp', 'name' );
}
if ( isset( $prop['limitreportdata'] ) ) {
$this->formatLimitReportData( $p_result->getLimitReportData() );
}
if ( isset( $prop['limitreporthtml'] ) ) {
- $limitreportHtml = EditPage::getPreviewLimitReport( $p_result );
- $result_array['limitreporthtml'] = array();
- ApiResult::setContentValue( $result_array['limitreporthtml'], 'limitreporthtml', $limitreportHtml );
+ $result_array['limitreporthtml'] = EditPage::getPreviewLimitReport( $p_result );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'limitreporthtml';
}
if ( $params['generatexml'] ) {
} else {
$xml = $dom->__toString();
}
- $result_array['parsetree'] = array();
- ApiResult::setContentValue( $result_array['parsetree'], 'parsetree', $xml );
+ $result_array['parsetree'] = $xml;
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
}
$result_mapping = array(
$entry['sortkey'] = $sortkey;
ApiResult::setContentValue( $entry, 'category', $link );
if ( !isset( $hiddencats[$link] ) ) {
- $entry['missing'] = '';
+ $entry['missing'] = true;
} elseif ( $hiddencats[$link] ) {
- $entry['hidden'] = '';
+ $entry['hidden'] = true;
}
$result[] = $entry;
}
$entry = array();
$entry['ns'] = $ns;
ApiResult::setContentValue( $entry, 'title', Title::makeTitle( $ns, $title )->getFullText() );
- if ( $id != 0 ) {
- $entry['exists'] = '';
- }
+ $entry['exists'] = $id != 0;
$result[] = $entry;
}
}
return $result;
}
- private function formatProperties( $properties ) {
- $result = array();
- foreach ( $properties as $name => $value ) {
- $entry = array();
- $entry['name'] = $name;
- ApiResult::setContentValue( $entry, 'value', $value );
- $result[] = $entry;
- }
-
- return $result;
- }
-
private function formatCss( $css ) {
$result = array();
foreach ( $css as $file => $link ) {
if ( !is_array( $value ) ) {
$value = array( $value );
}
- ApiResult::setIndexedTagName( $value, 'param' );
- ApiResult::setIndexedTagNameOnSubarrays( $value, 'param' );
+ ApiResult::setIndexedTagNameRecursive( $value, 'param' );
$entry = array_merge( $entry, $value );
$result[] = $entry;
}
'reason' => $params['reason']
);
if ( $cascade ) {
- $res['cascade'] = '';
+ $res['cascade'] = true;
}
$res['protections'] = $resultProtections;
$result = $this->getResult();
ApiQueryBase::addTitleInfo( $r, $title );
$page = WikiPage::factory( $title );
$page->doPurge(); // Directly purge and skip the UI part of purge().
- $r['purged'] = '';
+ $r['purged'] = true;
if ( $forceLinkUpdate || $forceRecursiveLinkUpdate ) {
if ( !$this->getUser()->pingLimiter( 'linkpurge' ) ) {
$title, null, $forceRecursiveLinkUpdate, $p_result );
DataUpdate::runUpdates( $updates );
- $r['linkupdate'] = '';
+ $r['linkupdate'] = true;
if ( $enableParserCache ) {
$pcache = ParserCache::singleton();
foreach ( $pageSet->getMissingTitles() as $fakeId => $title ) {
$vals = array();
ApiQueryBase::addTitleInfo( $vals, $title );
- $vals['missing'] = '';
+ $vals['missing'] = true;
$pages[$fakeId] = $vals;
}
// Report any invalid titles
foreach ( $pageSet->getInvalidTitles() as $fakeId => $title ) {
- $pages[$fakeId] = array( 'title' => $title, 'invalid' => '' );
+ $pages[$fakeId] = array( 'title' => $title, 'invalid' => true );
}
// Report any missing page ids
foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
$pages[$pageid] = array(
'pageid' => $pageid,
- 'missing' => ''
+ 'missing' => true
);
}
// Report special pages
foreach ( $pageSet->getSpecialTitles() as $fakeId => $title ) {
$vals = array();
ApiQueryBase::addTitleInfo( $vals, $title );
- $vals['special'] = '';
+ $vals['special'] = true;
if ( $title->isSpecialPage() &&
!SpecialPageFactory::exists( $title->getDBkey() )
) {
- $vals['missing'] = '';
+ $vals['missing'] = true;
} elseif ( $title->getNamespace() == NS_MEDIA &&
!wfFindFile( $title )
) {
- $vals['missing'] = '';
+ $vals['missing'] = true;
}
$pages[$fakeId] = $vals;
}
if ( count( $pages ) ) {
$pageSet->populateGeneratorData( $pages );
+ ApiResult::setArrayType( $pages, 'BCarray' );
if ( $this->mParams['indexpageids'] ) {
$pageIDs = array_keys( $pages );
$result->addValue( null, 'text', $exportxml, ApiResult::NO_SIZE_CHECK );
$result->addValue( null, 'mime', 'text/xml', ApiResult::NO_SIZE_CHECK );
} else {
- $r = array();
- ApiResult::setContentValue( $r, 'xml', $exportxml );
- $result->addValue( 'query', 'export', $r, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( 'query', 'export', $exportxml, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( 'query', ApiResult::META_BC_SUBELEMENTS, array( 'export' ) );
}
}
$item['files'] = intval( $row->cat_files );
$item['subcats'] = intval( $row->cat_subcats );
}
- if ( isset( $prop['hidden'] ) && $row->cat_hidden ) {
- $item['hidden'] = '';
+ if ( isset( $prop['hidden'] ) ) {
+ $item['hidden'] = (bool)$row->cat_hidden;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $item );
if ( !$fit ) {
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['fromid'] = intval( $row->pl_from );
}
$messageIsCustomised = isset( $customisedMessages['pages'][$langObj->ucfirst( $message )] );
if ( $customised === $messageIsCustomised ) {
if ( $customised ) {
- $a['customised'] = '';
+ $a['customised'] = true;
}
} else {
continue;
$msg = wfMessage( $message, $args )->inLanguage( $langObj );
if ( !$msg->exists() ) {
- $a['missing'] = '';
+ $a['missing'] = true;
} else {
// Check if the parser is enabled:
if ( $params['enableparser'] ) {
if ( isset( $prop['default'] ) ) {
$default = wfMessage( $message )->inLanguage( $langObj )->useDatabase( false );
if ( !$default->exists() ) {
- $a['defaultmissing'] = '';
+ $a['defaultmissing'] = true;
} elseif ( $default->plain() != $msgString ) {
$a['default'] = $default->plain();
}
$data['blockexpiry'] = $row->ipb_expiry;
}
if ( $row->ipb_deleted ) {
- $data['hidden'] = '';
+ $data['hidden'] = true;
}
if ( $fld_editcount ) {
$data['editcount'] = intval( $row->user_editcount );
$a = array( 'pageid' => intval( $row->page_id ) );
ApiQueryBase::addTitleInfo( $a, $t );
if ( $row->page_is_redirect ) {
- $a['redirect'] = '';
+ $a['redirect'] = true;
}
// Put all the results in an array first
$this->resultArr[$a['pageid']] = $a;
$a['pageid'] = intval( $row->page_id );
ApiQueryBase::addTitleInfo( $a, Title::makeTitle( $row->page_namespace, $row->page_title ) );
if ( $row->page_is_redirect ) {
- $a['redirect'] = '';
+ $a['redirect'] = true;
}
$parentID = $this->pageMap[$ns][$row->{$this->bl_title}];
// Put all the results in an array first
if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
$vals['fragment'] = $row->rd_fragment;
}
- if ( $fld_redirect && $row->page_is_redirect ) {
- $vals['redirect'] = '';
+ if ( $fld_redirect ) {
+ $vals['redirect'] = (bool)$row->page_is_redirect;
}
$fit = $this->addPageSubItem( $id, $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
break;
}
- $block = array();
+ $block = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_id ) {
$block['id'] = $row->ipb_id;
}
}
if ( $fld_flags ) {
// For clarity, these flags use the same names as their action=block counterparts
- if ( $row->ipb_auto ) {
- $block['automatic'] = '';
- }
- if ( $row->ipb_anon_only ) {
- $block['anononly'] = '';
- }
- if ( $row->ipb_create_account ) {
- $block['nocreate'] = '';
- }
- if ( $row->ipb_enable_autoblock ) {
- $block['autoblock'] = '';
- }
- if ( $row->ipb_block_email ) {
- $block['noemail'] = '';
- }
- if ( $row->ipb_deleted ) {
- $block['hidden'] = '';
- }
- if ( $row->ipb_allow_usertalk ) {
- $block['allowusertalk'] = '';
- }
+ $block['automatic'] = (bool)$row->ipb_auto;
+ $block['anononly'] = (bool)$row->ipb_anon_only;
+ $block['nocreate'] = (bool)$row->ipb_create_account;
+ $block['autoblock'] = (bool)$row->ipb_enable_autoblock;
+ $block['noemail'] = (bool)$row->ipb_block_email;
+ $block['hidden'] = (bool)$row->ipb_deleted;
+ $block['allowusertalk'] = (bool)$row->ipb_allow_usertalk;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
if ( !$fit ) {
if ( isset( $prop['timestamp'] ) ) {
$vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
}
- if ( isset( $prop['hidden'] ) && !is_null( $row->pp_propname ) ) {
- $vals['hidden'] = '';
+ if ( isset( $prop['hidden'] ) ) {
+ $vals['hidden'] = !is_null( $row->pp_propname );
}
$fit = $this->addPageSubItem( $row->cl_from, $vals );
$vals['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files;
$vals['files'] = intval( $row->cat_files );
$vals['subcats'] = intval( $row->cat_subcats );
- if ( $row->cat_hidden ) {
- $vals['hidden'] = '';
- }
+ $vals['hidden'] = (bool)$row->cat_hidden;
$fit = $this->addPageSubItems( $catids[$row->cat_title], $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $row->cat_title );
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = intval( $row->page_id );
}
}
if ( $fld_user || $fld_userid ) {
if ( $row->ar_deleted & Revision::DELETED_USER ) {
- $rev['userhidden'] = '';
+ $rev['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_USER, $user ) ) {
if ( $fld_comment || $fld_parsedcomment ) {
if ( $row->ar_deleted & Revision::DELETED_COMMENT ) {
- $rev['commenthidden'] = '';
+ $rev['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) {
}
}
- if ( $fld_minor && $row->ar_minor_edit == 1 ) {
- $rev['minor'] = '';
+ if ( $fld_minor ) {
+ $rev['minor'] = $row->ar_minor_edit == 1;
}
if ( $fld_len ) {
$rev['len'] = $row->ar_len;
}
if ( $fld_sha1 ) {
if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
- $rev['sha1hidden'] = '';
+ $rev['sha1hidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
}
if ( $fld_content ) {
if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
- $rev['texthidden'] = '';
+ $rev['texthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
}
if ( $anyHidden && ( $row->ar_deleted & Revision::DELETED_RESTRICTED ) ) {
- $rev['suppressed'] = '';
+ $rev['suppressed'] = true;
}
if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
$r = array(
'name' => $dupName,
'user' => $dupFile->getUser( 'text' ),
- 'timestamp' => wfTimestamp( TS_ISO_8601, $dupFile->getTimestamp() )
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $dupFile->getTimestamp() ),
+ 'shared' => !$dupFile->isLocal(),
);
- if ( !$dupFile->isLocal() ) {
- $r['shared'] = '';
- }
$fit = $this->addPageSubItem( $pageId, $r );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $image . '|' . $dupName );
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = intval( $row->page_id );
}
$result = $this->getResult();
ApiResult::setIndexedTagName( $repos, 'repo' );
+ ApiResult::setArrayTypeRecursive( $repos, 'assoc' );
+ ApiResult::setArrayType( $repos, 'array' );
$result->addValue( array( 'query' ), 'repos', $repos );
}
}
if ( $row->fa_deleted & File::DELETED_FILE ) {
- $file['filehidden'] = '';
+ $file['filehidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_COMMENT ) {
- $file['commenthidden'] = '';
+ $file['commenthidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_USER ) {
- $file['userhidden'] = '';
+ $file['userhidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_RESTRICTED ) {
// This file is deleted for normal admins
- $file['suppressed'] = '';
+ $file['suppressed'] = true;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $file );
ApiQueryBase::addTitleInfo( $entry, $title );
if ( $row->page_is_redirect ) {
- $entry['redirect'] = '';
+ $entry['redirect'] = true;
}
if ( $iwprefix ) {
);
}
$version = $opts['version'];
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
// Timestamp is shown even if the file is revdelete'd in interface
// so do same here.
if ( isset( $prop['timestamp'] ) ) {
if ( $user || $userid ) {
if ( $file->isDeleted( File::DELETED_USER ) ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( $canShowField( File::DELETED_USER ) ) {
$vals['userid'] = $file->getUser( 'id' );
}
if ( !$file->getUser( 'id' ) ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
if ( $pcomment || $comment ) {
if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( $canShowField( File::DELETED_COMMENT ) ) {
}
if ( $file->isDeleted( File::DELETED_FILE ) ) {
- $vals['filehidden'] = '';
+ $vals['filehidden'] = true;
$anyHidden = true;
}
$pageInfo['length'] = intval( $this->pageLength[$pageid] );
if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) {
- $pageInfo['redirect'] = '';
+ $pageInfo['redirect'] = true;
}
if ( $this->pageIsNew[$pageid] ) {
- $pageInfo['new'] = '';
+ $pageInfo['new'] = true;
}
}
ApiResult::setIndexedTagName( $pageInfo['restrictiontypes'], 'rt' );
}
- if ( $this->fld_watched && isset( $this->watched[$ns][$dbkey] ) ) {
- $pageInfo['watched'] = '';
+ if ( $this->fld_watched ) {
+ $pageInfo['watched'] = isset( $this->watched[$ns][$dbkey] );
}
if ( $this->fld_watchers ) {
$pageInfo['editurl'] = wfExpandUrl( $title->getFullURL( 'action=edit' ), PROTO_CURRENT );
$pageInfo['canonicalurl'] = wfExpandUrl( $title->getFullURL(), PROTO_CANONICAL );
}
- if ( $this->fld_readable && $title->userCan( 'read', $this->getUser() ) ) {
- $pageInfo['readable'] = '';
+ if ( $this->fld_readable ) {
+ $pageInfo['readable'] = $title->userCan( 'read', $this->getUser() );
}
if ( $this->fld_preload ) {
$pageInfo['actions'] = array();
foreach ( $this->params['testactions'] as $action ) {
$this->countTestedActions++;
- if ( $title->userCan( $action, $user ) ) {
- $pageInfo['actions'][$action] = '';
- }
+ $pageInfo['actions'][$action] = $title->userCan( $action, $user );
}
}
'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 )
);
if ( $row->pr_cascade ) {
- $a['cascade'] = '';
+ $a['cascade'] = true;
}
$this->protections[$title->getNamespace()][$title->getDBkey()][] = $a;
}
ApiQueryBase::addTitleInfo( $entry, $title );
if ( $row->page_is_redirect ) {
- $entry['redirect'] = '';
+ $entry['redirect'] = true;
}
if ( $lllang ) {
}
$vals = $this->extractRowInfo( $row );
- if ( !$vals ) {
- continue;
- }
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
private function extractRowInfo( $row ) {
$logEntry = DatabaseLogEntry::newFromRow( $row );
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
$anyHidden = false;
$user = $this->getUser();
if ( $this->fld_title || $this->fld_ids || $this->fld_details && $row->log_params !== '' ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_ACTION, $user ) ) {
if ( $this->fld_user || $this->fld_userid ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_USER, $user ) ) {
}
if ( !$row->log_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->log_comment ) ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_COMMENT, $user ) ) {
}
if ( $anyHidden && LogEventsList::isDeleted( $row, LogPage::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
* @return bool True if it fits in the result
*/
private function addPageProps( $result, $page, $props ) {
+ ApiResult::setArrayType( $props, 'assoc' );
$fit = $result->addValue( array( 'query', 'pages', $page ), 'pageprops', $props );
if ( !$fit ) {
}
if ( $resultPageSet === null ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = (int)$row->page_id;
}
'title' => $title->getPrefixedText(),
);
if ( $title->isSpecialPage() ) {
- $vals['special'] = '';
+ $vals['special'] = true;
} else {
$vals['pageid'] = intval( $title->getArticleId() );
}
$r = array( 'name' => $params['page'] );
if ( $qp->isCached() ) {
if ( !$qp->isCacheable() ) {
- $r['disabled'] = '';
+ $r['disabled'] = true;
} else {
- $r['cached'] = '';
+ $r['cached'] = true;
$ts = $qp->getCachedTimestamp();
if ( $ts ) {
$r['cachedtimestamp'] = wfTimestamp( TS_ISO_8601, $ts );
$vals = $this->extractRowInfo( $row );
/* Add that row's data to our final output. */
- if ( !$vals ) {
- continue;
- }
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
/* Create a new entry in the result for the title. */
if ( $this->fld_title || $this->fld_ids ) {
if ( $type === RC_LOG && ( $row->rc_deleted & LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( $type !== RC_LOG ||
/* Add user data and 'anon' flag, if user is anonymous. */
if ( $this->fld_user || $this->fld_userid ) {
if ( $row->rc_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_USER, $user ) ) {
}
if ( !$row->rc_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
/* Add flags, such as new, minor, bot. */
if ( $this->fld_flags ) {
- if ( $row->rc_bot ) {
- $vals['bot'] = '';
- }
- if ( $row->rc_type == RC_NEW ) {
- $vals['new'] = '';
- }
- if ( $row->rc_minor ) {
- $vals['minor'] = '';
- }
+ $vals['bot'] = (bool)$row->rc_bot;
+ $vals['new'] = $row->rc_type == RC_NEW;
+ $vals['minor'] = (bool)$row->rc_minor;
}
/* Add sizes of each revision. (Only available on 1.10+) */
/* Add edit summary / log summary. */
if ( $this->fld_comment || $this->fld_parsedcomment ) {
if ( $row->rc_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
}
if ( $this->fld_redirect ) {
- if ( $row->page_is_redirect ) {
- $vals['redirect'] = '';
- }
+ $vals['redirect'] = (bool)$row->page_is_redirect;
}
/* Add the patrolled flag */
- if ( $this->fld_patrolled && $row->rc_patrolled == 1 ) {
- $vals['patrolled'] = '';
- }
-
- if ( $this->fld_patrolled && ChangesList::isUnpatrolled( $row, $user ) ) {
- $vals['unpatrolled'] = '';
+ if ( $this->fld_patrolled ) {
+ $vals['patrolled'] = $row->rc_patrolled == 1;
+ $vals['unpatrolled'] = ChangesList::isUnpatrolled( $row, $user );
}
if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
if ( $row->rc_deleted & LogPage::DELETED_ACTION ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCanBitfield( $row->rc_deleted, LogPage::DELETED_ACTION, $user ) ) {
if ( $this->fld_sha1 && $row->rev_sha1 !== null ) {
if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
- $vals['sha1hidden'] = '';
+ $vals['sha1hidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rev_deleted, Revision::DELETED_TEXT, $user ) ) {
}
if ( $anyHidden && ( $row->rc_deleted & Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
}
}
- if ( $this->fld_flags && $revision->isMinor() ) {
- $vals['minor'] = '';
+ if ( $this->fld_flags ) {
+ $vals['minor'] = $revision->isMinor();
}
if ( $this->fld_user || $this->fld_userid ) {
if ( $revision->isDeleted( Revision::DELETED_USER ) ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( $revision->userCan( Revision::DELETED_USER, $user ) ) {
}
$userid = $revision->getUser( Revision::RAW );
if ( !$userid ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
if ( $this->fld_userid ) {
if ( $this->fld_sha1 ) {
if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
- $vals['sha1hidden'] = '';
+ $vals['sha1hidden'] = true;
$anyHidden = true;
}
if ( $revision->userCan( Revision::DELETED_TEXT, $user ) ) {
if ( $this->fld_comment || $this->fld_parsedcomment ) {
if ( $revision->isDeleted( Revision::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( $revision->userCan( Revision::DELETED_COMMENT, $user ) ) {
}
}
if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
- $vals['texthidden'] = '';
+ $vals['texthidden'] = true;
$anyHidden = true;
} elseif ( !$content ) {
- $vals['textmissing'] = '';
+ $vals['textmissing'] = true;
}
}
if ( $this->fld_content && $content ) {
}
$vals['parsetree'] = $xml;
} else {
- $vals['badcontentformatforparsetree'] = '';
+ $vals['badcontentformatforparsetree'] = true;
$this->setWarning( "Conversion to XML is supported for wikitext only, " .
$title->getPrefixedDBkey() .
" uses content model " . $content->getModel() );
$this->setWarning( "Template expansion is supported for wikitext only, " .
$title->getPrefixedDBkey() .
" uses content model " . $content->getModel() );
- $vals['badcontentformat'] = '';
+ $vals['badcontentformat'] = true;
$text = false;
}
}
$name = $title->getPrefixedDBkey();
$this->setWarning( "The requested format {$this->contentFormat} is not " .
"supported for content model $model used by $name" );
- $vals['badcontentformat'] = '';
+ $vals['badcontentformat'] = true;
$text = false;
} else {
$text = $content->serialize( $format );
$name = $title->getPrefixedDBkey();
$this->setWarning( "The requested format {$this->contentFormat} is not " .
"supported for content model $model used by $name" );
- $vals['diff']['badcontentformat'] = '';
+ $vals['diff']['badcontentformat'] = true;
$engine = null;
} else {
$difftocontent = ContentHandler::makeContent(
}
}
} else {
- $vals['diff']['notcached'] = '';
+ $vals['diff']['notcached'] = true;
}
}
if ( $anyHidden && $revision->isDeleted( Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
$allowFrom = array( '' );
$allowException = true;
if ( !$config->get( 'AllowExternalImages' ) ) {
- if ( $config->get( 'EnableImageWhitelist' ) ) {
- $data['imagewhitelistenabled'] = '';
- }
+ $data['imagewhitelistenabled'] = (bool)$config->get( 'EnableImageWhitelist' );
$allowFrom = $config->get( 'AllowExternalImagesFrom' );
$allowException = !empty( $allowFrom );
}
ApiResult::setIndexedTagName( $data['externalimages'], 'prefix' );
}
- if ( !$config->get( 'DisableLangConversion' ) ) {
- $data['langconversion'] = '';
- }
-
- if ( !$config->get( 'DisableTitleConversion' ) ) {
- $data['titleconversion'] = '';
- }
+ $data['langconversion'] = !$config->get( 'DisableLangConversion' );
+ $data['titleconversion'] = !$config->get( 'DisableTitleConversion' );
if ( $wgContLang->linkPrefixExtension() ) {
$linkPrefixCharset = $wgContLang->linkPrefixCharset();
}
$linktrail = $wgContLang->linkTrail();
- if ( $linktrail ) {
- $data['linktrail'] = $linktrail;
- } else {
- $data['linktrail'] = '';
- }
+ $data['linktrail'] = $linktrail ?: '';
$data['legaltitlechars'] = Title::legalChars();
ApiResult::setIndexedTagName( $data['variants'], 'lang' );
}
- if ( $wgContLang->isRTL() ) {
- $data['rtl'] = '';
- }
+ $data['rtl'] = $wgContLang->isRTL();
$data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
- if ( wfReadOnly() ) {
- $data['readonly'] = '';
+ $data['readonly'] = wfReadOnly();
+ if ( $data['readonly'] ) {
$data['readonlyreason'] = wfReadOnlyReason();
}
- if ( $config->get( 'EnableWriteAPI' ) ) {
- $data['writeapi'] = '';
- }
+ $data['writeapi'] = (bool)$config->get( 'EnableWriteAPI' );
$tz = $config->get( 'Localtimezone' );
$offset = $config->get( 'LocalTZoffset' );
$data['scriptpath'] = $config->get( 'ScriptPath' );
$data['script'] = $config->get( 'Script' );
$data['variantarticlepath'] = $config->get( 'VariantArticlePath' );
+ $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
$data['server'] = $config->get( 'Server' );
$data['servername'] = $config->get( 'ServerName' );
$data['wikiid'] = wfWikiID();
$data['time'] = wfTimestamp( TS_ISO_8601, time() );
- if ( $config->get( 'MiserMode' ) ) {
- $data['misermode'] = '';
- }
+ $data['misermode'] = (bool)$config->get( 'MiserMode' );
$data['maxuploadsize'] = UploadBase::getMaxUploadSize();
$data['thumblimits'] = $config->get( 'ThumbLimits' );
+ ApiResult::setArrayType( $data['thumblimits'], 'BCassoc' );
ApiResult::setIndexedTagName( $data['thumblimits'], 'limit' );
$data['imagelimits'] = array();
+ ApiResult::setArrayType( $data['imagelimits'], 'BCassoc' );
ApiResult::setIndexedTagName( $data['imagelimits'], 'limit' );
foreach ( $config->get( 'ImageLimits' ) as $k => $limit ) {
$data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
protected function appendNamespaces( $property ) {
global $wgContLang;
- $data = array();
+ $data = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
$data[$ns] = array(
'id' => intval( $ns ),
ApiResult::setContentValue( $data[$ns], 'name', $title );
$canonical = MWNamespace::getCanonicalName( $ns );
- if ( MWNamespace::hasSubpages( $ns ) ) {
- $data[$ns]['subpages'] = '';
- }
+ $data[$ns]['subpages'] = MWNamespace::hasSubpages( $ns );
if ( $canonical ) {
$data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
}
- if ( MWNamespace::isContent( $ns ) ) {
- $data[$ns]['content'] = '';
- }
-
- if ( MWNamespace::isNonincludable( $ns ) ) {
- $data[$ns]['nonincludable'] = '';
- }
+ $data[$ns]['content'] = MWNamespace::isContent( $ns );
+ $data[$ns]['nonincludable'] = MWNamespace::isNonincludable( $ns );
$contentmodel = MWNamespace::getNamespaceContentModel( $ns );
if ( $contentmodel ) {
foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
$caseSensitive = array_shift( $aliases );
$arr = array( 'name' => $magicword, 'aliases' => $aliases );
- if ( $caseSensitive ) {
- $arr['case-sensitive'] = '';
- }
+ $arr['case-sensitive'] = (bool)$caseSensitive;
ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
$data[] = $arr;
}
$val = array();
$val['prefix'] = $prefix;
if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
- $val['local'] = '';
+ $val['local'] = true;
}
if ( isset( $row['iw_trans'] ) && $row['iw_trans'] == '1' ) {
- $val['trans'] = '';
+ $val['trans'] = true;
}
if ( isset( $langNames[$prefix] ) ) {
$val['language'] = $langNames[$prefix];
}
if ( in_array( $prefix, $localInterwikis ) ) {
- $val['localinterwiki'] = '';
+ $val['localinterwiki'] = true;
}
if ( in_array( $prefix, $extraLangPrefixes ) ) {
- $val['extralanglink'] = '';
+ $val['extralanglink'] = true;
$linktext = wfMessage( "interlanguage-link-$prefix" );
if ( !$linktext->isDisabled() ) {
}
$val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
- if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
- $val['protorel'] = '';
- }
+ $val['protorel'] = substr( $row['iw_url'], 0, 2 ) == '//';
if ( isset( $row['iw_wikiid'] ) && $row['iw_wikiid'] !== '' ) {
$val['wikiid'] = $row['iw_wikiid'];
}
$skin = array( 'code' => $name );
ApiResult::setContentValue( $skin, 'name', $displayName );
if ( !isset( $allowed[$name] ) ) {
- $skin['unusable'] = '';
+ $skin['unusable'] = true;
}
if ( $name === $default ) {
- $skin['default'] = '';
+ $skin['default'] = true;
}
$data[] = $skin;
}
}
public function appendDefaultOptions( $property ) {
- return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
+ $options = User::getDefaultOptions();
+ $options[ApiResult::META_BC_BOOLS] = array_keys( $options );
+ return $this->getResult()->addValue( 'query', $property, $options );
}
private function formatParserTags( $item ) {
$isExtension = isset( $extensionDefinedTags[$tagName] );
$isExplicit = isset( $explicitlyDefinedTags[$tagName] );
- if ( $fld_defined && ( $isExtension || $isExplicit ) ) {
- $tag['defined'] = '';
+ if ( $fld_defined ) {
+ $tag['defined'] = $isExtension || $isExplicit;
}
if ( $fld_source ) {
}
}
- if ( $fld_active &&
- ( $isExplicit || isset( $extensionActivatedTags[$tagName] ) )
- ) {
- $tag['active'] = '';
+ if ( $fld_active ) {
+ $tag['active'] = $isExplicit || isset( $extensionActivatedTags[$tagName] );
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $tag );
public function execute() {
$params = $this->extractRequestParams();
- $res = array();
+ $res = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $this->lacksSameOriginSecurity() ) {
$this->setWarning( 'Tokens may not be obtained when the same-origin policy is not applied' );
$anyHidden = false;
if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
- $vals['texthidden'] = '';
+ $vals['texthidden'] = true;
$anyHidden = true;
}
$vals['userid'] = $row->rev_user;
$vals['user'] = $row->rev_user_text;
if ( $row->rev_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( $this->fld_ids ) {
}
if ( $this->fld_flags ) {
- if ( $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id ) ) {
- $vals['new'] = '';
- }
- if ( $row->rev_minor_edit ) {
- $vals['minor'] = '';
- }
- if ( $row->page_latest == $row->rev_id ) {
- $vals['top'] = '';
- }
+ $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
+ $vals['minor'] = (bool)$row->rev_minor_edit;
+ $vals['top'] = $row->page_latest == $row->rev_id;
}
if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->rev_comment ) ) {
if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
}
}
- if ( $this->fld_patrolled && $row->rc_patrolled ) {
- $vals['patrolled'] = '';
+ if ( $this->fld_patrolled ) {
+ $vals['patrolled'] = (bool)$row->rc_patrolled;
}
if ( $this->fld_size && !is_null( $row->rev_len ) ) {
}
if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
$vals['name'] = $user->getName();
if ( $user->isAnon() ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
if ( isset( $this->prop['blockinfo'] ) ) {
}
}
- if ( isset( $this->prop['hasmsg'] ) && $user->getNewtalk() ) {
- $vals['messages'] = '';
+ if ( isset( $this->prop['hasmsg'] ) ) {
+ $vals['messages'] = $user->getNewtalk();
}
if ( isset( $this->prop['groups'] ) ) {
$vals['groups'] = $user->getEffectiveGroups();
+ ApiResult::setArrayType( $vals['groups'], 'array' ); // even if empty
ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
}
if ( isset( $this->prop['implicitgroups'] ) ) {
$vals['implicitgroups'] = $user->getAutomaticGroups();
+ ApiResult::setArrayType( $vals['implicitgroups'], 'array' ); // even if empty
ApiResult::setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
}
if ( isset( $this->prop['rights'] ) ) {
// User::getRights() may return duplicate values, strip them
$vals['rights'] = array_values( array_unique( $user->getRights() ) );
+ ApiResult::setArrayType( $vals['rights'], 'array' ); // even if empty
ApiResult::setIndexedTagName( $vals['rights'], 'r' ); // even if empty
}
if ( isset( $this->prop['options'] ) ) {
$vals['options'] = $user->getOptions();
+ $vals['options'][ApiResult::META_BC_BOOLS] = array_keys( $vals['options'] );
}
if ( isset( $this->prop['preferencestoken'] ) ) {
}
protected function getRateLimits() {
+ $retval = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
+
$user = $this->getUser();
if ( !$user->isPingLimitable() ) {
- return array(); // No limits
+ return $retval; // No limits
}
// Find out which categories we belong to
$categories = array_merge( $categories, $user->getGroups() );
// Now get the actual limits
- $retval = array();
foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
foreach ( $categories as $cat ) {
if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) ) {
foreach ( $users as $u ) {
$n = User::getCanonicalName( $u );
if ( $n === false || $n === '' ) {
- $vals = array( 'name' => $u, 'invalid' => '' );
+ $vals = array( 'name' => $u, 'invalid' => true );
$fit = $result->addValue( array( 'query', $this->getModuleName() ),
null, $vals );
if ( !$fit ) {
$data[$name]['rights'] = $user->getRights();
}
if ( $row->ipb_deleted ) {
- $data[$name]['hidden'] = '';
+ $data[$name]['hidden'] = true;
}
if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) {
$data[$name]['blockid'] = $row->ipb_id;
$data[$name]['blockexpiry'] = $row->ipb_expiry;
}
- if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) {
- $data[$name]['emailable'] = '';
+ if ( isset( $this->prop['emailable'] ) ) {
+ $data[$name]['emailable'] = $user->canReceiveEmail();
}
if ( isset( $this->prop['gender'] ) ) {
$iwUser = $urPage->fetchUser( $u );
if ( $iwUser instanceof UserRightsProxy ) {
- $data[$u]['interwiki'] = '';
+ $data[$u]['interwiki'] = true;
if ( !is_null( $params['token'] ) ) {
$tokenFunctions = $this->getTokenFunctions();
}
}
} else {
- $data[$u]['missing'] = '';
+ $data[$u]['missing'] = true;
}
} else {
if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) {
+ ApiResult::setArrayType( $data[$u]['groups'], 'array' );
ApiResult::setIndexedTagName( $data[$u]['groups'], 'g' );
}
if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) {
+ ApiResult::setArrayType( $data[$u]['implicitgroups'], 'array' );
ApiResult::setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
}
if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) {
+ ApiResult::setArrayType( $data[$u]['rights'], 'array' );
ApiResult::setIndexedTagName( $data[$u]['rights'], 'r' );
}
}
if ( $this->fld_title || $this->fld_ids ) {
// These should already have been filtered out of the query, but just in case.
if ( $type === RC_LOG && ( $row->rc_deleted & LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( $type !== RC_LOG ||
/* Add user data and 'anon' flag, if user is anonymous. */
if ( $this->fld_user || $this->fld_userid ) {
if ( $row->rc_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_USER, $user ) ) {
}
if ( !$row->rc_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
/* Add flags, such as new, minor, bot. */
if ( $this->fld_flags ) {
- if ( $row->rc_bot ) {
- $vals['bot'] = '';
- }
- if ( $row->rc_type == RC_NEW ) {
- $vals['new'] = '';
- }
- if ( $row->rc_minor ) {
- $vals['minor'] = '';
- }
+ $vals['bot'] = (bool)$row->rc_bot;
+ $vals['new'] = $row->rc_type == RC_NEW;
+ $vals['minor'] = (bool)$row->rc_minor;
}
/* Add sizes of each revision. (Only available on 1.10+) */
/* Add edit summary / log summary. */
if ( $this->fld_comment || $this->fld_parsedcomment ) {
if ( $row->rc_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
}
/* Add the patrolled flag */
- if ( $this->fld_patrol && $row->rc_patrolled == 1 ) {
- $vals['patrolled'] = '';
- }
-
- if ( $this->fld_patrol && ChangesList::isUnpatrolled( $row, $user ) ) {
- $vals['unpatrolled'] = '';
+ if ( $this->fld_patrol ) {
+ $vals['patrolled'] = $row->rc_patrolled == 1;
+ $vals['unpatrolled'] = ChangesList::isUnpatrolled( $row, $user );
}
if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
if ( $row->rc_deleted & LogPage::DELETED_ACTION ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCanBitfield( $row->rc_deleted, LogPage::DELETED_ACTION, $user ) ) {
}
if ( $anyHidden && ( $row->rc_deleted & Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
* Clear the current result data.
*/
public function reset() {
- $this->data = array();
+ $this->data = array(
+ self::META_TYPE => 'assoc', // Usually what's desired
+ );
$this->size = 0;
}
}
/**
- * Alias for self::defineIndexedTagName()
+ * Alias for self::addIndexedTagName()
* @deprecated since 1.25, use $this->addIndexedTagName() instead
* @param array $path Path to the array, like addValue()'s $path
* @param string $tag
foreach ( $pageSet->getInvalidTitles() as $title ) {
$r = array();
$r['title'] = $title;
- $r['invalid'] = '';
+ $r['invalid'] = true;
$result[] = $r;
}
foreach ( $pageSet->getMissingPageIDs() as $p ) {
$page = array();
$page['pageid'] = $p;
- $page['missing'] = '';
- $page['notwatched'] = '';
+ $page['missing'] = true;
+ $page['notwatched'] = true;
$result[] = $page;
}
foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
$rev = array();
$rev['revid'] = $r;
- $rev['missing'] = '';
- $rev['notwatched'] = '';
+ $rev['missing'] = true;
+ $rev['notwatched'] = true;
$result[] = $rev;
}
'title' => $title->getPrefixedText(),
);
if ( !$title->exists() ) {
- $r['missing'] = '';
+ $r['missing'] = true;
}
if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
$r['notificationtimestamp'] = '';
$r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $timestamps[$ns][$dbkey] );
}
} else {
- $r['notwatched'] = '';
+ $r['notwatched'] = true;
}
$result[] = $r;
}
$this->logFeatureUsage( "action=tokens" );
$params = $this->extractRequestParams();
- $res = array();
+ $res = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
$types = $this->getTokenTypes();
foreach ( $params['type'] as $type ) {
if ( $params['unwatch'] ) {
$status = UnwatchAction::doUnwatch( $title, $user );
+ $res['unwatched'] = $status->isOK();
if ( $status->isOK() ) {
- $res['unwatched'] = '';
$res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
->title( $title )->parseAsBlock();
}
} else {
$status = WatchAction::doWatch( $title, $user );
+ $res['watched'] = $status->isOK();
if ( $status->isOK() ) {
- $res['watched'] = '';
$res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
->title( $title )->parseAsBlock();
}
'gcontinue' => 3,
'continue' => 'gcontinue||',
), $result->getResultData( 'continue' ) );
- $this->assertSame( '', $result->getResultData( 'batchcomplete' ) );
+ $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
$manager = self::getManager( '', $allModules, array( 'mock1', 'mock2' ) );
$this->assertSame( false, $manager->isGeneratorDone() );
$result = new ApiResult( 8388608 );
$formatter = new ApiErrorFormatter( $result, Language::factory( $lang ), $format, $useDB );
+ // Add default type
+ $expect1[ApiResult::META_TYPE] = 'assoc';
+ $expect2[ApiResult::META_TYPE] = 'assoc';
+ $expect3[ApiResult::META_TYPE] = 'assoc';
+
$formatter->addWarning( 'string', 'mainpage' );
$formatter->addError( 'err', 'mainpage' );
$this->assertSame( $expect1, $result->getResultData(), 'Simple test' );
ApiResult::META_CONTENT => 'warnings',
),
),
+ ApiResult::META_TYPE => 'assoc',
), $result->getResultData(), 'Simple test' );
$result->reset();
ApiResult::META_CONTENT => 'warnings',
),
),
+ ApiResult::META_TYPE => 'assoc',
), $result->getResultData(), 'Complex test' );
$result->reset();
ApiResult::META_CONTENT => 'warnings',
),
),
+ ApiResult::META_TYPE => 'assoc',
), $result->getResultData(), 'Status test' );
$I = ApiResult::META_INDEXED_TAG_NAME;
$result2 = new ApiResult( 8388608 );
$result2->addValue( null, 'foo', 'bar' );
ApiResult::setValue( $arr, 'baz', $result2 );
- $this->assertSame( array( 'baz' => array( 'foo' => 'bar' ) ), $arr );
+ $this->assertSame( array(
+ 'baz' => array(
+ ApiResult::META_TYPE => 'assoc',
+ 'foo' => 'bar',
+ )
+ ), $arr );
$arr = array();
ApiResult::setValue( $arr, 'foo', "foo\x80bar" );
'unnamed 2',
'a' => array( 'b' => array() ),
'setContentValue' => '3',
+ ApiResult::META_TYPE => 'assoc',
ApiResult::META_CONTENT => 'setContentValue',
), $result->getResultData() );
$this->assertSame( 20, $result->getSize() );
$result->getResultData( array( ApiResult::META_CONTENT ) ) );
$result->reset();
- $this->assertSame( array(), $result->getResultData() );
+ $this->assertSame( array(
+ ApiResult::META_TYPE => 'assoc',
+ ), $result->getResultData() );
$this->assertSame( 0, $result->getSize() );
$result->addValue( null, 'foo', 1 );
$result->addValue( null, 'bottom', '2' );
$result->addValue( null, 'foo', '2', ApiResult::OVERRIDE );
$result->addValue( null, 'bar', '2', ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP );
- $this->assertSame( array( 0, 'top', 'foo', 'bar', 'bottom' ),
+ $this->assertSame( array( 0, 'top', 'foo', 'bar', 'bottom', ApiResult::META_TYPE ),
array_keys( $result->getResultData() ) );
$result->reset();
$result->reset();
$result->addValue( null, 'sub', array( 'foo' => 1 ) );
$result->addValue( null, 'sub', array( 'bar' => 1 ) );
- $this->assertSame( array( 'sub' => array( 'foo' => 1, 'bar' => 1 ) ),
- $result->getResultData() );
+ $this->assertSame( array(
+ 'sub' => array( 'foo' => 1, 'bar' => 1 ),
+ ApiResult::META_TYPE => 'assoc',
+ ), $result->getResultData() );
try {
$result->addValue( null, 'sub', array( 'foo' => 2, 'baz' => 2 ) );
$this->assertSame( array(
'title' => (string)$title,
'obj' => array( 'foo' => 1, 'bar' => 2, ApiResult::META_TYPE => 'assoc' ),
+ ApiResult::META_TYPE => 'assoc',
), $result->getResultData() );
$fh = tmpfile();
$result->reset();
$result->addParsedLimit( 'foo', 12 );
- $this->assertSame( array( 'limits' => array( 'foo' => 12 ) ), $result->getResultData() );
+ $this->assertSame( array(
+ 'limits' => array( 'foo' => 12 ),
+ ApiResult::META_TYPE => 'assoc',
+ ), $result->getResultData() );
$result->addParsedLimit( 'foo', 13 );
- $this->assertSame( array( 'limits' => array( 'foo' => 13 ) ), $result->getResultData() );
+ $this->assertSame( array(
+ 'limits' => array( 'foo' => 13 ),
+ ApiResult::META_TYPE => 'assoc',
+ ), $result->getResultData() );
$this->assertSame( null, $result->getResultData( array( 'foo', 'bar', 'baz' ) ) );
$this->assertSame( 13, $result->getResultData( array( 'limits', 'foo' ) ) );
try {
$result2 = new ApiResult( 8388608 );
$result2->addValue( null, 'foo', 'bar' );
$result->addValue( null, 'baz', $result2 );
- $this->assertSame( array( 'baz' => array( 'foo' => 'bar' ) ), $result->getResultData() );
+ $this->assertSame( array(
+ 'baz' => array(
+ 'foo' => 'bar',
+ ApiResult::META_TYPE => 'assoc',
+ ),
+ ApiResult::META_TYPE => 'assoc',
+ ), $result->getResultData() );
$result = new ApiResult( 8388608 );
$result->addValue( null, 'foo', "foo\x80bar" );
'foo' => "foo\xef\xbf\xbdbar",
'bar' => "\xc3\xa1",
'baz' => 74,
+ ApiResult::META_TYPE => 'assoc',
), $result->getResultData() );
}
$result->removePreserveKeysList( null, 'baz' );
$result->addArrayTypeRecursive( null, 'default' );
$result->addArrayType( null, 'array' );
- $this->assertSame( $expect, $result->getResultData() );
+ $this->assertEquals( $expect, $result->getResultData() );
$arr = array( 'foo' => array( 'bar' => array() ) );
$expect = array(
'gcontinue' => 3,
'continue' => 'gcontinue||',
), $result->getResultData( 'continue' ) );
- $this->assertSame( '', $result->getResultData( 'batchcomplete' ) );
+ $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
$this->assertSame( array(
'mocklist' => array( 'mlcontinue' => 2 ),
'generator' => array( 'gcontinue' => 3 ),
'gcontinue' => 3,
'continue' => 'gcontinue||mocklist',
), $result->getResultData( 'continue' ) );
- $this->assertSame( '', $result->getResultData( 'batchcomplete' ) );
+ $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
$this->assertSame( array(
'generator' => array( 'gcontinue' => 3 ),
), $result->getResultData( 'query-continue' ) );
'mlcontinue' => 2,
'continue' => '-||mock1|mock2',
), $result->getResultData( 'continue' ) );
- $this->assertSame( '', $result->getResultData( 'batchcomplete' ) );
+ $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
$this->assertSame( array(
'mocklist' => array( 'mlcontinue' => 2 ),
), $result->getResultData( 'query-continue' ) );
$result->endContinuation( 'raw' );
$result->endContinuation( 'standard' );
$this->assertSame( null, $result->getResultData( 'continue' ) );
- $this->assertSame( '', $result->getResultData( 'batchcomplete' ) );
+ $this->assertSame( true, $result->getResultData( 'batchcomplete' ) );
$this->assertSame( null, $result->getResultData( 'query-continue' ) );
$main->setContinuationManager( null );
$main->getModuleManager()->addModule( $this->printerName, 'format', $class );
}
$result = $main->getResult();
+ $result->addArrayType( null, 'default' );
foreach ( $data as $k => $v ) {
$result->addValue( null, $k, $v );
}
};
// generator + 1 prop + 1 list
$data = $this->query( $mk( 99, 99, true ), 1, 'g1p', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1, true ), 6, 'g1p-11t' );
$this->checkC( $data, $mk( 2, 2, true ), 3, 'g1p-22t' );
$this->checkC( $data, $mk( 1, 1, false ), 6, 'g1p-11f' );
);
};
$data = $this->query( $mk( 99 ), 1, '1L', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
// 1 list
$this->checkC( $data, $mk( 1 ), 5, '1L-1' );
};
// 2 lists
$data = $this->query( $mk( 99, 99 ), 1, '2L', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1 ), 5, '2L-11' );
$this->checkC( $data, $mk( 2, 2 ), 3, '2L-22' );
$this->checkC( $data, $mk( 3, 3 ), 2, '2L-33' );
};
// generator + 1 prop
$data = $this->query( $mk( 99, 99 ), 1, 'G1P', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1 ), 11, 'G1P-11' );
$this->checkC( $data, $mk( 2, 2 ), 6, 'G1P-22' );
$this->checkC( $data, $mk( 3, 3 ), 4, 'G1P-33' );
};
// generator + 2 props
$data = $this->query( $mk( 99, 99, 99 ), 1, 'G2P', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1, 1 ), 16, 'G2P-111' );
$this->checkC( $data, $mk( 2, 2, 2 ), 9, 'G2P-222' );
$this->checkC( $data, $mk( 3, 3, 3 ), 6, 'G2P-333' );
};
// generator + 1 prop + 1 list
$data = $this->query( $mk( 99, 99, 99 ), 1, 'G1P1L', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1, 1 ), 11, 'G1P1L-111' );
$this->checkC( $data, $mk( 2, 2, 2 ), 6, 'G1P1L-222' );
$this->checkC( $data, $mk( 3, 3, 3 ), 4, 'G1P1L-333' );
};
// generator + 1 prop + 1 list
$data = $this->query( $mk( 99, 99, 99, 99, 99 ), 1, 'G2P2L1M', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, 1, 1, 1, 1 ), 16, 'G2P2L1M-11111' );
$this->checkC( $data, $mk( 2, 2, 2, 2, 2 ), 9, 'G2P2L1M-22222' );
$this->checkC( $data, $mk( 3, 3, 3, 3, 3 ), 6, 'G2P2L1M-33333' );
};
// generator + 1 prop
$data = $this->query( $mk( 99, true, 99, true ), 1, 'G=P', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, true, 1, true ), 4, 'G=P-1t1t' );
$this->checkC( $data, $mk( 2, true, 2, true ), 2, 'G=P-2t2t' );
};
// generator + 1 list
$data = $this->query( $mk( 99, true, 99, true ), 1, 'G=L', false ) +
- array( 'batchcomplete' => '' );
+ array( 'batchcomplete' => true );
$this->checkC( $data, $mk( 1, true, 1, true ), 5, 'G=L-1t1t' );
$this->checkC( $data, $mk( 2, true, 2, true ), 3, 'G=L-2t2t' );