Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.21% covered (success)
92.21%
71 / 77
75.00% covered (warning)
75.00%
6 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiChangeContentModel
93.42% covered (success)
93.42%
71 / 76
75.00% covered (warning)
75.00%
6 / 8
15.06
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
1 / 1
6
 getAllowedParams
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
3
 mustBePosted
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isWriteMode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 needsToken
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Api;
4
5use MediaWiki\Content\IContentHandlerFactory;
6use MediaWiki\Page\ContentModelChangeFactory;
7use Wikimedia\ParamValidator\ParamValidator;
8use Wikimedia\Rdbms\IDBAccessObject;
9
10/**
11 * Api module to change the content model of existing pages
12 *
13 * For new pages, use the edit api and specify the desired content model and format.
14 *
15 * @since 1.35
16 * @ingroup API
17 * @author DannyS712
18 */
19class ApiChangeContentModel extends ApiBase {
20
21    private IContentHandlerFactory $contentHandlerFactory;
22    private ContentModelChangeFactory $contentModelChangeFactory;
23
24    public function __construct(
25        ApiMain $main,
26        string $action,
27        IContentHandlerFactory $contentHandlerFactory,
28        ContentModelChangeFactory $contentModelChangeFactory
29    ) {
30        parent::__construct( $main, $action );
31        $this->contentHandlerFactory = $contentHandlerFactory;
32        $this->contentModelChangeFactory = $contentModelChangeFactory;
33    }
34
35    /**
36     * A lot of this code is based on SpecialChangeContentModel
37     */
38    public function execute() {
39        $params = $this->extractRequestParams();
40        $wikiPage = $this->getTitleOrPageId( $params );
41        $title = $wikiPage->getTitle();
42        $this->getErrorFormatter()->setContextTitle( $title );
43
44        if ( !$title->exists() ) {
45            $this->dieWithError( 'apierror-changecontentmodel-missingtitle' );
46        }
47
48        $newModel = $params['model'];
49
50        $this->checkUserRightsAny( 'editcontentmodel' );
51        $changer = $this->contentModelChangeFactory->newContentModelChange(
52            $this->getAuthority(),
53            $wikiPage,
54            $newModel
55        );
56        // Status messages should be apierror-*
57        $changer->setMessagePrefix( 'apierror-' );
58        $permissionStatus = $changer->authorizeChange();
59        if ( !$permissionStatus->isGood() ) {
60            $this->dieStatus( $permissionStatus );
61        }
62
63        if ( $params['tags'] ) {
64            $tagStatus = $changer->setTags( $params['tags'] );
65            if ( !$tagStatus->isGood() ) {
66                $this->dieStatus( $tagStatus );
67            }
68        }
69
70        // Everything passed, make the conversion
71        $status = $changer->doContentModelChange(
72            $this->getContext(),
73            $params['summary'] ?? '',
74            $params['bot']
75        );
76
77        if ( !$status->isGood() ) {
78            // Failed
79            $this->dieStatus( $status );
80        }
81        $logid = $status->getValue()['logid'];
82
83        $result = [
84            'result' => 'Success',
85            'title' => $title->getPrefixedText(),
86            'pageid' => $title->getArticleID(),
87            'contentmodel' => $title->getContentModel( IDBAccessObject::READ_LATEST ),
88            'logid' => $logid,
89            'revid' => $title->getLatestRevID( IDBAccessObject::READ_LATEST ),
90        ];
91
92        $this->getResult()->addValue( null, $this->getModuleName(), $result );
93    }
94
95    public function getAllowedParams() {
96        $models = $this->contentHandlerFactory->getContentModels();
97        $modelOptions = [];
98        foreach ( $models as $model ) {
99            $handler = $this->contentHandlerFactory->getContentHandler( $model );
100            if ( !$handler->supportsDirectEditing() ) {
101                continue;
102            }
103            $modelOptions[] = $model;
104        }
105
106        return [
107            'title' => [
108                ParamValidator::PARAM_TYPE => 'string',
109            ],
110            'pageid' => [
111                ParamValidator::PARAM_TYPE => 'integer',
112            ],
113            'summary' => [
114                ParamValidator::PARAM_TYPE => 'string',
115            ],
116            'tags' => [
117                ParamValidator::PARAM_TYPE => 'tags',
118                ParamValidator::PARAM_ISMULTI => true,
119            ],
120            'model' => [
121                ParamValidator::PARAM_TYPE => $modelOptions,
122                ParamValidator::PARAM_REQUIRED => true,
123            ],
124            'bot' => false,
125        ];
126    }
127
128    public function mustBePosted() {
129        return true;
130    }
131
132    public function isWriteMode() {
133        return true;
134    }
135
136    public function needsToken() {
137        return 'csrf';
138    }
139
140    public function getHelpUrls() {
141        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel';
142    }
143
144    protected function getExamplesMessages() {
145        return [
146            'action=changecontentmodel&title=Main Page&model=text&token=123ABC'
147                => 'apihelp-changecontentmodel-example'
148        ];
149    }
150}
151
152/** @deprecated class alias since 1.43 */
153class_alias( ApiChangeContentModel::class, 'ApiChangeContentModel' );