Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiReview
0.00% covered (danger)
0.00%
0 / 72
0.00% covered (danger)
0.00%
0 / 5
650
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
380
 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
12
 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 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * Created on Dec 20, 2008
5 *
6 * API module for MediaWiki's FlaggedRevs extension
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
22 */
23
24use MediaWiki\MediaWikiServices;
25use MediaWiki\Title\Title;
26use Wikimedia\ParamValidator\ParamValidator;
27
28/**
29 * API module to review revisions
30 *
31 * @ingroup FlaggedRevs
32 */
33class ApiReview extends ApiBase {
34
35    /**
36     * The method checks basic permissions of the user to interact
37     * with the page. Then it submits the form of the revision on
38     * approve or unapprove action. It also generates the template
39     * parameters itself.
40     */
41    public function execute() {
42        $params = $this->extractRequestParams();
43        // Check basic permissions
44        $this->checkUserRightsAny( 'review' );
45
46        // Get target rev and title
47        $revid = (int)$params['revid'];
48        $revRecord = MediaWikiServices::getInstance()
49            ->getRevisionLookup()
50            ->getRevisionById( $revid );
51        if ( !$revRecord ) {
52            $this->dieWithError( [ 'apierror-nosuchrevid', $revid ], 'notarget' );
53        }
54
55        $linkTarget = $revRecord->getPageAsLinkTarget();
56        if ( $this->getPermissionManager()->isBlockedFrom( $this->getUser(), $linkTarget, false ) ) {
57            // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Guaranteed via isBlockedFrom() above
58            $this->dieBlocked( $this->getUser()->getBlock() );
59        }
60
61        $title = Title::newFromLinkTarget( $linkTarget );
62
63        // Construct submit form...
64        $form = new RevisionReviewForm( $this->getUser() );
65        $form->setTitle( $title );
66        $form->setOldId( $revid );
67        $form->setAction( $params['unapprove'] ?
68            RevisionReviewForm::ACTION_UNAPPROVE :
69            RevisionReviewForm::ACTION_APPROVE );
70        if ( isset( $params['comment'] ) ) {
71            $form->setComment( $params['comment'] );
72        }
73        // The flagging parameter has the form 'flag_$name' ($name varies
74        // by wiki). Extract it and put the value into $form->tag.
75        $form->setTag( FlaggedRevs::binaryFlagging() ?
76            1 :
77            (int)$params['flag_' . FlaggedRevs::getTagName() ]
78        );
79        if ( $form->getAction() === RevisionReviewForm::ACTION_APPROVE ) {
80            $form->bypassValidationKey(); // always OK; uses current templates
81        }
82
83        $form->ready(); // all params set
84
85        # Try to do the actual review
86        $status = $form->submit();
87        # Approve/de-approve success
88        if ( $status === true ) {
89            $this->getResult()->addValue(
90                null, $this->getModuleName(), [ 'result' => 'Success' ] );
91        # Generic failures
92        } elseif ( $status === 'review_page_notexists' ) {
93            $this->dieWithError( 'apierror-flaggedrevs-pagedoesnotexist', 'notarget' );
94        } elseif ( $status === 'review_page_unreviewable' ) {
95            $this->dieWithError( 'apierror-flaggedrevs-notreviewable', 'notreviewable' );
96        # Approve-specific failures
97        } elseif ( $form->getAction() === RevisionReviewForm::ACTION_APPROVE ) {
98            if ( $status === 'review_denied' ) {
99                $this->dieWithError( 'apierror-flaggedrevs-cantreview', 'permissiondenied' );
100            } elseif ( $status === 'review_too_low' ) {
101                $this->dieWithError( 'apierror-flaggedrevs-toolow', 'mixedapproval' );
102            } elseif ( $status === 'review_bad_key' ) {
103                $this->dieWithError( 'apierror-flaggedrevs-cantreview', 'permissiondenied' );
104            } elseif ( $status === 'review_bad_tags' ) {
105                $this->dieWithError( 'apierror-flaggedrevs-badflags', 'invalidtags' );
106            } elseif ( $status === 'review_bad_oldid' ) {
107                $this->dieWithError( [ 'apierror-nosuchrevid', $revid ], 'notarget' );
108            } else {
109                // FIXME: review_param_missing? better msg?
110                $this->dieWithError( [ 'apierror-unknownerror-nocode' ], 'unknownerror' );
111            }
112        # De-approve specific failure
113        } elseif ( $form->getAction() === RevisionReviewForm::ACTION_UNAPPROVE ) {
114            if ( $status === 'review_denied' ) {
115                $this->dieWithError( 'apierror-flaggedrevs-cantunreview', 'permissiondenied' );
116            } elseif ( $status === 'review_not_flagged' ) {
117                $this->dieWithError( 'apierror-flaggedrevs-noflaggedrev', 'notarget' );
118            } else {
119                // FIXME: review_param_missing? better msg?
120                $this->dieWithError( [ 'apierror-unknownerror-nocode' ], 'unknownerror' );
121            }
122        }
123    }
124
125    /**
126     * @inheritDoc
127     */
128    public function isWriteMode() {
129        return true;
130    }
131
132    /**
133     * @inheritDoc
134     */
135    protected function getAllowedParams() {
136        $pars = [
137            'revid' => null,
138            'comment' => null,
139            'unapprove' => false
140        ];
141        if ( !FlaggedRevs::binaryFlagging() && !FlaggedRevs::useOnlyIfProtected() ) {
142            $strLevels = array_map( 'strval', range( 0, FlaggedRevs::getMaxLevel() ) );
143            $pars['flag_' . FlaggedRevs::getTagName()] = [
144                ParamValidator::PARAM_DEFAULT => '1', // default
145                ParamValidator::PARAM_TYPE => $strLevels, // array of allowed values
146                ApiBase::PARAM_HELP_MSG => [ 'apihelp-review-param-flag', FlaggedRevs::getTagName() ],
147            ];
148        }
149        return $pars;
150    }
151
152    /**
153     * @return string
154     */
155    public function needsToken() {
156        return 'csrf';
157    }
158
159    /**
160     * @inheritDoc
161     */
162    protected function getExamplesMessages() {
163        return [
164            'action=review&revid=12345&token=123AB&flag_accuracy=1&comment=Ok'
165                => 'apihelp-review-example-1',
166        ];
167    }
168}