X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryRevisionsBase.php;h=d0b152edb1b3d165dd3876d881b5be0e90cbd463;hb=f2da0e29cfa02571d5649a01d9238b92e7ade662;hp=0d2aeab1994a5ec3ef3d599420bab63110e546f5;hpb=1900a8a12e8e1445fa8b9cca46a89354fcc88f1d;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryRevisionsBase.php b/includes/api/ApiQueryRevisionsBase.php index 0d2aeab199..d0b152edb1 100644 --- a/includes/api/ApiQueryRevisionsBase.php +++ b/includes/api/ApiQueryRevisionsBase.php @@ -20,6 +20,7 @@ * @file */ +use MediaWiki\Logger\LoggerFactory; use MediaWiki\Revision\RevisionAccessException; use MediaWiki\Revision\RevisionRecord; use MediaWiki\Revision\SlotRecord; @@ -229,9 +230,9 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { $anyHidden = false; if ( $this->fld_ids ) { - $vals['revid'] = intval( $revision->getId() ); + $vals['revid'] = (int)$revision->getId(); if ( !is_null( $revision->getParentId() ) ) { - $vals['parentid'] = intval( $revision->getParentId() ); + $vals['parentid'] = (int)$revision->getParentId(); } } @@ -267,7 +268,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { if ( $this->fld_size ) { try { - $vals['size'] = intval( $revision->getSize() ); + $vals['size'] = (int)$revision->getSize(); } catch ( RevisionAccessException $e ) { // Back compat: If there's no size, return 0. // @todo: Gergő says to mention T198099 as a "todo" here. @@ -292,69 +293,27 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { } } - if ( $this->fld_roles ) { - $vals['roles'] = $revision->getSlotRoles(); - } - - if ( $this->needSlots ) { - $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT ); - if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) { - $anyHidden = true; + try { + if ( $this->fld_roles ) { + $vals['roles'] = $revision->getSlotRoles(); } - if ( $this->slotRoles === null ) { - try { - $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW ); - } catch ( RevisionAccessException $e ) { - // Back compat: If there's no slot, there's no content, so set 'textmissing' - // @todo: Gergő says to mention T198099 as a "todo" here. - $vals['textmissing'] = true; - $slot = null; - } - if ( $slot ) { - $content = null; - $vals += $this->extractSlotInfo( $slot, $revDel, $content ); - if ( !empty( $vals['nosuchsection'] ) ) { - $this->dieWithError( - [ - 'apierror-nosuchsection-what', - wfEscapeWikiText( $this->section ), - $this->msg( 'revid', $revision->getId() ) - ], - 'nosuchsection' - ); - } - if ( $content ) { - $vals += $this->extractDeprecatedContent( $content, $revision ); - } + if ( $this->needSlots ) { + $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT ); + if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) { + $anyHidden = true; } - } else { - $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() ); - $vals['slots'] = [ - ApiResult::META_KVP_MERGE => true, - ]; - foreach ( $roles as $role ) { - try { - $slot = $revision->getSlot( $role, RevisionRecord::RAW ); - } catch ( RevisionAccessException $e ) { - // Don't error out here so the client can still process other slots/revisions. - // @todo: Gergő says to mention T198099 as a "todo" here. - $vals['slots'][$role]['missing'] = true; - continue; - } - $content = null; - $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content ); - // @todo Move this into extractSlotInfo() (and remove its $content parameter) - // when extractDeprecatedContent() is no more. - if ( $content ) { - $vals['slots'][$role]['contentmodel'] = $content->getModel(); - $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat(); - ApiResult::setContentValue( $vals['slots'][$role], 'content', $content->serialize() ); - } - } - ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' ); - ApiResult::setIndexedTagName( $vals['slots'], 'slot' ); + $vals = array_merge( $vals, $this->extractAllSlotInfo( $revision, $revDel ) ); } + } catch ( RevisionAccessException $ex ) { + // This is here so T212428 doesn't spam the log. + // TODO: find out why T212428 happens in the first place! + $vals['slotsmissing'] = true; + + LoggerFactory::getInstance( 'api-warning' )->error( + 'Failed to access revision slots', + [ 'revision' => $revision->getId(), 'exception' => $ex, ] + ); } if ( $this->fld_comment || $this->fld_parsedcomment ) { @@ -396,6 +355,79 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { return $vals; } + /** + * Extracts information about all relevant slots. + * + * @param RevisionRecord $revision + * @param int $revDel + * + * @return array + * @throws ApiUsageException + */ + private function extractAllSlotInfo( RevisionRecord $revision, $revDel ): array { + $vals = []; + + if ( $this->slotRoles === null ) { + try { + $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW ); + } catch ( RevisionAccessException $e ) { + // Back compat: If there's no slot, there's no content, so set 'textmissing' + // @todo: Gergő says to mention T198099 as a "todo" here. + $vals['textmissing'] = true; + $slot = null; + } + + if ( $slot ) { + $content = null; + $vals += $this->extractSlotInfo( $slot, $revDel, $content ); + if ( !empty( $vals['nosuchsection'] ) ) { + $this->dieWithError( + [ + 'apierror-nosuchsection-what', + wfEscapeWikiText( $this->section ), + $this->msg( 'revid', $revision->getId() ) + ], + 'nosuchsection' + ); + } + if ( $content ) { + $vals += $this->extractDeprecatedContent( $content, $revision ); + } + } + } else { + $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() ); + $vals['slots'] = [ + ApiResult::META_KVP_MERGE => true, + ]; + foreach ( $roles as $role ) { + try { + $slot = $revision->getSlot( $role, RevisionRecord::RAW ); + } catch ( RevisionAccessException $e ) { + // Don't error out here so the client can still process other slots/revisions. + // @todo: Gergő says to mention T198099 as a "todo" here. + $vals['slots'][$role]['missing'] = true; + continue; + } + $content = null; + $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content ); + // @todo Move this into extractSlotInfo() (and remove its $content parameter) + // when extractDeprecatedContent() is no more. + if ( $content ) { + $vals['slots'][$role]['contentmodel'] = $content->getModel(); + $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat(); + ApiResult::setContentValue( + $vals['slots'][$role], + 'content', + $content->serialize() + ); + } + } + ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' ); + ApiResult::setIndexedTagName( $vals['slots'], 'slot' ); + } + return $vals; + } + /** * Extract information from the SlotRecord * @@ -410,7 +442,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { ApiResult::setArrayType( $vals, 'assoc' ); if ( $this->fld_slotsize ) { - $vals['size'] = intval( $slot->getSize() ); + $vals['size'] = (int)$slot->getSize(); } if ( $this->fld_slotsha1 ) { @@ -464,8 +496,6 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { * @return array */ private function extractDeprecatedContent( Content $content, RevisionRecord $revision ) { - global $wgParser; - $vals = []; $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() ); @@ -473,12 +503,13 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) { $t = $content->getText(); # note: don't set $text - $wgParser->startExternalParse( + $parser = MediaWikiServices::getInstance()->getParser(); + $parser->startExternalParse( $title, ParserOptions::newFromContext( $this->getContext() ), Parser::OT_PREPROCESS ); - $dom = $wgParser->preprocessToDom( $t ); + $dom = $parser->preprocessToDom( $t ); if ( is_callable( [ $dom, 'saveXML' ] ) ) { $xml = $dom->saveXML(); } else { @@ -505,7 +536,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase { if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) { $text = $content->getText(); - $text = $wgParser->preprocess( + $text = MediaWikiServices::getInstance()->getParser()->preprocess( $text, $title, ParserOptions::newFromContext( $this->getContext() )