X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiMain.php;h=a8db20cedf4d897fd2440881f22f15c6f03023a7;hb=a54306065e6c94af524ff2a9e7d97501d7ca0405;hp=297845361d733bdb3a6c0c823b6a053eaad879a4;hpb=1a4928389f999b76a0be196f8b7586e194f01295;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 297845361d..a8db20cedf 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -89,6 +89,7 @@ class ApiMain extends ApiBase { 'imagerotate' => 'ApiImageRotate', 'revisiondelete' => 'ApiRevisionDelete', 'managetags' => 'ApiManageTags', + 'tag' => 'ApiTag', ); /** @@ -139,7 +140,7 @@ class ApiMain extends ApiBase { */ private $mPrinter; - private $mModuleMgr, $mResult; + private $mModuleMgr, $mResult, $mErrorFormatter, $mContinuationManager; private $mAction; private $mEnableWrite; private $mInternalMode, $mSquidMaxage, $mModule; @@ -217,7 +218,11 @@ class ApiMain extends ApiBase { Hooks::run( 'ApiMain::moduleManager', array( $this->mModuleMgr ) ); - $this->mResult = new ApiResult( $this ); + $this->mResult = new ApiResult( $this->getConfig()->get( 'APIMaxResultSize' ) ); + $this->mErrorFormatter = new ApiErrorFormatter_BackCompat( $this->mResult ); + $this->mResult->setErrorFormatter( $this->mErrorFormatter ); + $this->mResult->setMainForContinuation( $this ); + $this->mContinuationManager = null; $this->mEnableWrite = $enableWrite; $this->mSquidMaxage = -1; // flag for executeActionWithErrorHandling() @@ -241,6 +246,43 @@ class ApiMain extends ApiBase { return $this->mResult; } + /** + * Get the ApiErrorFormatter object associated with current request + * @return ApiErrorFormatter + */ + public function getErrorFormatter() { + return $this->mErrorFormatter; + } + + /** + * Get the continuation manager + * @return ApiContinuationManager|null + */ + public function getContinuationManager() { + return $this->mContinuationManager; + } + + /** + * Set the continuation manager + * @param ApiContinuationManager|null + */ + public function setContinuationManager( $manager ) { + if ( $manager !== null ) { + if ( !$manager instanceof ApiContinuationManager ) { + throw new InvalidArgumentException( __METHOD__ . ': Was passed ' . + is_object( $manager ) ? get_class( $manager ) : gettype( $manager ) + ); + } + if ( $this->mContinuationManager !== null ) { + throw new UnexpectedValueException( + __METHOD__ . ': tried to set manager from ' . $manager->getSource() . + ' when a manager is already set from ' . $this->mContinuationManager->getSource() + ); + } + } + $this->mContinuationManager = $manager; + } + /** * Get the API module object. Only works after executeAction() * @@ -453,7 +495,22 @@ class ApiMain extends ApiBase { // Reset and print just the error message ob_clean(); - $this->printResult( true ); + // Printer may not be initialized if the extractRequestParams() fails for the main module + $this->createErrorPrinter(); + + try { + $this->printResult( true ); + } catch ( UsageException $ex ) { + // The error printer itself is failing. Try suppressing its request + // parameters and redo. + $this->setWarning( + 'Error printer failed (will retry without params): ' . $ex->getMessage() + ); + $this->mPrinter = null; + $this->createErrorPrinter(); + $this->mPrinter->forceDefaultParams(); + $this->printResult( true ); + } } /** @@ -520,8 +577,7 @@ class ApiMain extends ApiBase { if ( !in_array( $originParam, $origins ) ) { // origin parameter set but incorrect // Send a 403 response - $message = HttpStatus::getMessage( 403 ); - $response->header( "HTTP/1.1 403 $message", true, 403 ); + $response->statusHeader( 403 ); $response->header( 'Cache-Control: no-cache' ); echo "'origin' parameter does not match Origin header\n"; @@ -750,22 +806,14 @@ class ApiMain extends ApiBase { } /** - * Replace the result data with the information about an exception. - * Returns the error code - * @param Exception $e - * @return string + * Create the printer for error output */ - protected function substituteResultWithError( $e ) { - $result = $this->getResult(); - - // Printer may not be initialized if the extractRequestParams() fails for the main module + private function createErrorPrinter() { if ( !isset( $this->mPrinter ) ) { - // The printer has not been created yet. Try to manually get formatter value. $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT ); if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) { $value = self::API_DEFAULT_FORMAT; } - $this->mPrinter = $this->createPrinterByName( $value ); } @@ -774,17 +822,23 @@ class ApiMain extends ApiBase { if ( !$this->mPrinter->canPrintErrors() ) { $this->mPrinter = $this->createPrinterByName( self::API_DEFAULT_FORMAT ); } + } - // Update raw mode flag for the selected printer. - $result->setRawMode( $this->mPrinter->getNeedsRawData() ); - + /** + * Replace the result data with the information about an exception. + * Returns the error code + * @param Exception $e + * @return string + */ + protected function substituteResultWithError( $e ) { + $result = $this->getResult(); $config = $this->getConfig(); if ( $e instanceof UsageException ) { // User entered incorrect parameters - generate error response $errMessage = $e->getMessageArray(); $link = wfExpandUrl( wfScript( 'api' ) ); - ApiResult::setContent( $errMessage, "See $link for API usage" ); + ApiResult::setContentValue( $errMessage, 'docref', "See $link for API usage" ); } else { // Something is seriously wrong if ( ( $e instanceof DBQueryError ) && !$config->get( 'ShowSQLErrors' ) ) { @@ -798,16 +852,16 @@ class ApiMain extends ApiBase { 'info' => '[' . MWExceptionHandler::getLogId( $e ) . '] ' . $info, ); if ( $config->get( 'ShowExceptionDetails' ) ) { - ApiResult::setContent( + ApiResult::setContentValue( $errMessage, + 'trace', MWExceptionHandler::getRedactedTraceAsString( $e ) ); } } // Remember all the warnings to re-add them later - $oldResult = $result->getData(); - $warnings = isset( $oldResult['warnings'] ) ? $oldResult['warnings'] : null; + $warnings = $result->getResultData( array( 'warnings' ) ); $result->reset(); // Re-add the id @@ -1190,9 +1244,7 @@ class ApiMain extends ApiBase { $this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' ); } - $this->getResult()->cleanUpUTF8(); $printer = $this->mPrinter; - $printer->initPrinter( false ); $printer->execute(); $printer->closePrinter(); @@ -1254,7 +1306,7 @@ class ApiMain extends ApiBase { ); } - public function modifyHelp( array &$help, array $options ) { + public function modifyHelp( array &$help, array $options, array &$tocData ) { // Wish PHP had an "array_insert_before". Instead, we have to manually // reindex the array to get 'permissions' in the right place. $oldHelp = $help; @@ -1265,6 +1317,7 @@ class ApiMain extends ApiBase { } $help[$k] = $v; } + $help['datatypes'] = ''; $help['credits'] = ''; // Fill 'permissions' @@ -1297,13 +1350,48 @@ class ApiMain extends ApiBase { $help['permissions'] .= Html::closeElement( 'dl' ); $help['permissions'] .= Html::closeElement( 'div' ); - // Fill 'credits', if applicable + // Fill 'datatypes' and 'credits', if applicable if ( empty( $options['nolead'] ) ) { - $help['credits'] .= Html::element( 'h' . min( 6, $options['headerlevel'] + 1 ), - array( 'id' => '+credits', 'class' => 'apihelp-header' ), - $this->msg( 'api-credits-header' )->parse() + $level = $options['headerlevel']; + $tocnumber = &$options['tocnumber']; + + $header = $this->msg( 'api-help-datatypes-header' )->parse(); + $help['datatypes'] .= Html::rawelement( 'h' . min( 6, $level ), + array( 'id' => 'main/datatypes', 'class' => 'apihelp-header' ), + Html::element( 'span', array( 'id' => Sanitizer::escapeId( 'main/datatypes' ) ) ) . + $header + ); + $help['datatypes'] .= $this->msg( 'api-help-datatypes' )->parseAsBlock(); + if ( !isset( $tocData['main/datatypes'] ) ) { + $tocnumber[$level]++; + $tocData['main/datatypes'] = array( + 'toclevel' => count( $tocnumber ), + 'level' => $level, + 'anchor' => 'main/datatypes', + 'line' => $header, + 'number' => join( '.', $tocnumber ), + 'index' => false, + ); + } + + $header = $this->msg( 'api-credits-header' )->parse(); + $help['credits'] .= Html::rawelement( 'h' . min( 6, $level ), + array( 'id' => 'main/credits', 'class' => 'apihelp-header' ), + Html::element( 'span', array( 'id' => Sanitizer::escapeId( 'main/credits' ) ) ) . + $header ); $help['credits'] .= $this->msg( 'api-credits' )->useDatabase( false )->parseAsBlock(); + if ( !isset( $tocData['main/credits'] ) ) { + $tocnumber[$level]++; + $tocData['main/credits'] = array( + 'toclevel' => count( $tocnumber ), + 'level' => $level, + 'anchor' => 'main/credits', + 'line' => $header, + 'number' => join( '.', $tocnumber ), + 'index' => false, + ); + } } }