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    /** @inheritDoc */
96    public function getAllowedParams() {
97        $models = $this->contentHandlerFactory->getContentModels();
98        $modelOptions = [];
99        foreach ( $models as $model ) {
100            $handler = $this->contentHandlerFactory->getContentHandler( $model );
101            if ( !$handler->supportsDirectEditing() ) {
102                continue;
103            }
104            $modelOptions[] = $model;
105        }
106
107        return [
108            'title' => [
109                ParamValidator::PARAM_TYPE => 'string',
110            ],
111            'pageid' => [
112                ParamValidator::PARAM_TYPE => 'integer',
113            ],
114            'summary' => [
115                ParamValidator::PARAM_TYPE => 'string',
116            ],
117            'tags' => [
118                ParamValidator::PARAM_TYPE => 'tags',
119                ParamValidator::PARAM_ISMULTI => true,
120            ],
121            'model' => [
122                ParamValidator::PARAM_TYPE => $modelOptions,
123                ParamValidator::PARAM_REQUIRED => true,
124            ],
125            'bot' => false,
126        ];
127    }
128
129    /** @inheritDoc */
130    public function mustBePosted() {
131        return true;
132    }
133
134    /** @inheritDoc */
135    public function isWriteMode() {
136        return true;
137    }
138
139    /** @inheritDoc */
140    public function needsToken() {
141        return 'csrf';
142    }
143
144    /** @inheritDoc */
145    public function getHelpUrls() {
146        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel';
147    }
148
149    /** @inheritDoc */
150    protected function getExamplesMessages() {
151        return [
152            'action=changecontentmodel&title=Main Page&model=text&token=123ABC'
153                => 'apihelp-changecontentmodel-example'
154        ];
155    }
156}
157
158/** @deprecated class alias since 1.43 */
159class_alias( ApiChangeContentModel::class, 'ApiChangeContentModel' );