Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
54 / 57
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CreationHandler
94.74% covered (success)
94.74%
54 / 57
75.00% covered (warning)
75.00%
3 / 4
9.01
0.00% covered (danger)
0.00%
0 / 1
 getTitleParameter
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getParamSettings
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
1 / 1
1
 getActionModuleParameters
84.21% covered (warning)
84.21%
16 / 19
0.00% covered (danger)
0.00%
0 / 1
6.14
 mapActionModuleResponse
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Rest\Handler;
4
5use MediaWiki\Request\WebResponse;
6use MediaWiki\Rest\LocalizedHttpException;
7use MediaWiki\Rest\Response;
8use Wikimedia\Message\MessageValue;
9use Wikimedia\ParamValidator\ParamValidator;
10
11/**
12 * Core REST API endpoint that handles page creation (main slot only)
13 */
14class CreationHandler extends EditHandler {
15
16    /**
17     * @inheritDoc
18     */
19    protected function getTitleParameter() {
20        $body = $this->getValidatedBody();
21        '@phan-var array $body';
22        return $body['title'];
23    }
24
25    /**
26     * @inheritDoc
27     * @return array
28     */
29    public function getParamSettings() {
30        return [
31            'source' => [
32                self::PARAM_SOURCE => 'body',
33                ParamValidator::PARAM_TYPE => 'string',
34                ParamValidator::PARAM_REQUIRED => true,
35                self::PARAM_DESCRIPTION => 'The intended content of the page',
36            ],
37            'title' => [
38                self::PARAM_SOURCE => 'body',
39                ParamValidator::PARAM_TYPE => 'string',
40                ParamValidator::PARAM_REQUIRED => true,
41                self::PARAM_DESCRIPTION => 'The title of the page to create',
42            ],
43            'comment' => [
44                self::PARAM_SOURCE => 'body',
45                ParamValidator::PARAM_TYPE => 'string',
46                ParamValidator::PARAM_REQUIRED => true,
47                self::PARAM_DESCRIPTION => 'A comment descripting the reason for creating the page',
48            ],
49            'content_model' => [
50                self::PARAM_SOURCE => 'body',
51                ParamValidator::PARAM_TYPE => 'string',
52                ParamValidator::PARAM_REQUIRED => false,
53                self::PARAM_DESCRIPTION => 'The content model to use to interpret the source',
54            ],
55        ]
56            + $this->getTokenParamDefinition()
57            + parent::getParamSettings();
58    }
59
60    /**
61     * @inheritDoc
62     */
63    protected function getActionModuleParameters() {
64        $body = $this->getValidatedBody();
65        '@phan-var array $body';
66
67        $title = $this->getTitleParameter();
68
69        $contentmodel = $body['content_model'] ?: null;
70
71        if ( $contentmodel !== null && !$this->contentHandlerFactory->isDefinedModel( $contentmodel ) ) {
72            throw new LocalizedHttpException(
73                new MessageValue( 'rest-bad-content-model', [ $body['content_model'] ] ), 400
74            );
75        }
76
77        // Use a known good CSRF token if a token is not needed because we are
78        // using a method of authentication that protects against CSRF, like OAuth.
79        $token = $this->needsToken() ? $this->getToken() : $this->getUser()->getEditToken();
80
81        $params = [
82            'action' => 'edit',
83            'title' => $title,
84            'text' => $body['source'],
85            'summary' => $body['comment'],
86            'token' => $token,
87            'createonly' => true,
88        ];
89
90        if ( $contentmodel !== null ) {
91            $params['contentmodel'] = $contentmodel;
92        }
93
94        return $params;
95    }
96
97    protected function mapActionModuleResponse(
98        WebResponse $actionModuleResponse,
99        array $actionModuleResult,
100        Response $response
101    ) {
102        parent::mapActionModuleResponse(
103            $actionModuleResponse,
104            $actionModuleResult,
105            $response
106        );
107
108        $title = $this->urlEncodeTitle( $actionModuleResult['edit']['title'] );
109
110        $url = $this->getRouter()->getRouteUrl( '/v1/page/' . $title );
111        $response->setHeader( 'Location', $url );
112    }
113
114}