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