Since we introduced support for the "body" PARAM_SOURCE in getParamSettings, fields in the request body can be defined in the same way that path and query parameters are defined. However, body fields are treated separately by the framework, and the value of body fields are available through getValidatedBody(), rather than getValidatedParams(). Because of that, it makes sense to have a method that returns the param settings just for the body fields. This also allows handler classes to override this method separately to specify body fields. That way, it also becomes possible to have body fields that have the same name as other parameters. Bug: T362850 Change-Id: Ia85bf7e46c949a999052d91f1b0d7d579a880108
113 lines
2.9 KiB
PHP
113 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Rest\Handler;
|
|
|
|
use MediaWiki\Request\WebResponse;
|
|
use MediaWiki\Rest\LocalizedHttpException;
|
|
use MediaWiki\Rest\Response;
|
|
use Wikimedia\Message\MessageValue;
|
|
use Wikimedia\ParamValidator\ParamValidator;
|
|
|
|
/**
|
|
* Core REST API endpoint that handles page creation (main slot only)
|
|
*/
|
|
class CreationHandler extends EditHandler {
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
protected function getTitleParameter() {
|
|
$body = $this->getValidatedBody();
|
|
'@phan-var array $body';
|
|
return $body['title'];
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
* @return array
|
|
*/
|
|
public function getBodyParamSettings(): array {
|
|
return [
|
|
'source' => [
|
|
self::PARAM_SOURCE => 'body',
|
|
ParamValidator::PARAM_TYPE => 'string',
|
|
ParamValidator::PARAM_REQUIRED => true,
|
|
self::PARAM_DESCRIPTION => 'The intended content of the page',
|
|
],
|
|
'title' => [
|
|
self::PARAM_SOURCE => 'body',
|
|
ParamValidator::PARAM_TYPE => 'string',
|
|
ParamValidator::PARAM_REQUIRED => true,
|
|
self::PARAM_DESCRIPTION => 'The title of the page to create',
|
|
],
|
|
'comment' => [
|
|
self::PARAM_SOURCE => 'body',
|
|
ParamValidator::PARAM_TYPE => 'string',
|
|
ParamValidator::PARAM_REQUIRED => true,
|
|
self::PARAM_DESCRIPTION => 'A comment descripting the reason for creating the page',
|
|
],
|
|
'content_model' => [
|
|
self::PARAM_SOURCE => 'body',
|
|
ParamValidator::PARAM_TYPE => 'string',
|
|
ParamValidator::PARAM_REQUIRED => false,
|
|
self::PARAM_DESCRIPTION => 'The content model to use to interpret the source',
|
|
],
|
|
]
|
|
+ $this->getTokenParamDefinition();
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
protected function getActionModuleParameters() {
|
|
$body = $this->getValidatedBody();
|
|
'@phan-var array $body';
|
|
|
|
$title = $this->getTitleParameter();
|
|
|
|
$contentmodel = $body['content_model'] ?: null;
|
|
|
|
if ( $contentmodel !== null && !$this->contentHandlerFactory->isDefinedModel( $contentmodel ) ) {
|
|
throw new LocalizedHttpException(
|
|
new MessageValue( 'rest-bad-content-model', [ $body['content_model'] ] ), 400
|
|
);
|
|
}
|
|
|
|
// Use a known good CSRF token if a token is not needed because we are
|
|
// using a method of authentication that protects against CSRF, like OAuth.
|
|
$token = $this->needsToken() ? $this->getToken() : $this->getUser()->getEditToken();
|
|
|
|
$params = [
|
|
'action' => 'edit',
|
|
'title' => $title,
|
|
'text' => $body['source'],
|
|
'summary' => $body['comment'],
|
|
'token' => $token,
|
|
'createonly' => true,
|
|
];
|
|
|
|
if ( $contentmodel !== null ) {
|
|
$params['contentmodel'] = $contentmodel;
|
|
}
|
|
|
|
return $params;
|
|
}
|
|
|
|
protected function mapActionModuleResponse(
|
|
WebResponse $actionModuleResponse,
|
|
array $actionModuleResult,
|
|
Response $response
|
|
) {
|
|
parent::mapActionModuleResponse(
|
|
$actionModuleResponse,
|
|
$actionModuleResult,
|
|
$response
|
|
);
|
|
|
|
$title = $this->urlEncodeTitle( $actionModuleResult['edit']['title'] );
|
|
|
|
$url = $this->getRouter()->getRouteUrl( '/v1/page/' . $title );
|
|
$response->setHeader( 'Location', $url );
|
|
}
|
|
|
|
}
|