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