Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiFileRevert
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 9
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
12
 validateParameters
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
 mustBePosted
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isWriteMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 needsToken
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 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2011 Bryan Tong Minh <Bryan.TongMinh@Gmail.com>
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Api;
10
11use MediaWiki\FileRepo\File\LocalFile;
12use MediaWiki\FileRepo\RepoGroup;
13use MediaWiki\Title\Title;
14use Wikimedia\ParamValidator\ParamValidator;
15
16/**
17 * @ingroup API
18 */
19class ApiFileRevert extends ApiBase {
20    /** @var LocalFile */
21    protected $file;
22
23    /** @var string */
24    protected $archiveName;
25
26    /** @var array */
27    protected $params;
28
29    /** @var RepoGroup */
30    private $repoGroup;
31
32    public function __construct(
33        ApiMain $main,
34        string $action,
35        RepoGroup $repoGroup
36    ) {
37        parent::__construct( $main, $action );
38        $this->repoGroup = $repoGroup;
39    }
40
41    public function execute() {
42        $this->useTransactionalTimeLimit();
43
44        $this->params = $this->extractRequestParams();
45        // Extract the file and archiveName from the request parameters
46        $this->validateParameters();
47
48        // Check whether we're allowed to revert this file
49        $this->checkTitleUserPermissions( $this->file->getTitle(), [ 'edit', 'upload' ] );
50        $rights = [ 'reupload' ];
51        if ( $this->getUser()->equals( $this->file->getUploader() ) ) {
52            // reupload-own is more basic, put it in the front for error messages.
53            array_unshift( $rights, 'reupload-own' );
54        }
55        $this->checkUserRightsAny( $rights );
56
57        $sourceUrl = $this->file->getArchiveVirtualUrl( $this->archiveName );
58        $status = $this->file->upload(
59            $sourceUrl,
60            $this->params['comment'],
61            $this->params['comment'],
62            0,
63            false,
64            false,
65            $this->getAuthority()
66        );
67
68        if ( $status->isGood() ) {
69            $result = [ 'result' => 'Success' ];
70        } else {
71            $result = [
72                'result' => 'Failure',
73                'errors' => $this->getErrorFormatter()->arrayFromStatus( $status ),
74            ];
75        }
76
77        $this->getResult()->addValue( null, $this->getModuleName(), $result );
78    }
79
80    /**
81     * Validate the user parameters and set $this->archiveName and $this->file.
82     * Throws an error if validation fails
83     */
84    protected function validateParameters() {
85        // Validate the input title
86        $title = Title::makeTitleSafe( NS_FILE, $this->params['filename'] );
87        if ( $title === null ) {
88            $this->dieWithError(
89                [ 'apierror-invalidtitle', wfEscapeWikiText( $this->params['filename'] ) ]
90            );
91        }
92        $localRepo = $this->repoGroup->getLocalRepo();
93
94        // Check if the file really exists
95        $this->file = $localRepo->newFile( $title );
96        if ( !$this->file->exists() ) {
97            $this->dieWithError( 'apierror-missingtitle' );
98        }
99
100        // Check if the archivename is valid for this file
101        $this->archiveName = $this->params['archivename'];
102        // @phan-suppress-next-line PhanTypeMismatchArgumentNullable T240141
103        $oldFile = $localRepo->newFromArchiveName( $title, $this->archiveName );
104        if ( !$oldFile->exists() ) {
105            $this->dieWithError( 'filerevert-badversion' );
106        }
107    }
108
109    /** @inheritDoc */
110    public function mustBePosted() {
111        return true;
112    }
113
114    /** @inheritDoc */
115    public function isWriteMode() {
116        return true;
117    }
118
119    /** @inheritDoc */
120    public function getAllowedParams() {
121        return [
122            'filename' => [
123                ParamValidator::PARAM_TYPE => 'string',
124                ParamValidator::PARAM_REQUIRED => true,
125            ],
126            'comment' => [
127                ParamValidator::PARAM_DEFAULT => '',
128            ],
129            'archivename' => [
130                ParamValidator::PARAM_TYPE => 'string',
131                ParamValidator::PARAM_REQUIRED => true,
132            ],
133        ];
134    }
135
136    /** @inheritDoc */
137    public function needsToken() {
138        return 'csrf';
139    }
140
141    /** @inheritDoc */
142    protected function getExamplesMessages() {
143        return [
144            'action=filerevert&filename=Wiki.png&comment=Revert&' .
145                'archivename=20110305152740!Wiki.png&token=123ABC'
146                => 'apihelp-filerevert-example-revert',
147        ];
148    }
149
150    /** @inheritDoc */
151    public function getHelpUrls() {
152        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Filerevert';
153    }
154}
155
156/** @deprecated class alias since 1.43 */
157class_alias( ApiFileRevert::class, 'ApiFileRevert' );