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\Api\ApiBase;
25use MediaWiki\MediaWikiServices;
26use MediaWiki\Title\Title;
27use Wikimedia\ParamValidator\ParamValidator;
28
29/**
30 * API module to review revisions
31 *
32 * @ingroup FlaggedRevs
33 */
34class ApiReview extends ApiBase {
35
36    /**
37     * The method checks basic permissions of the user to interact
38     * with the page. Then it submits the form of the revision on
39     * approve or unapprove action. It also generates the template
40     * parameters itself.
41     */
42    public function execute() {
43        $params = $this->extractRequestParams();
44        // Check basic permissions
45        $this->checkUserRightsAny( 'review' );
46
47        // Get target rev and title
48        $revid = (int)$params['revid'];
49        $revRecord = MediaWikiServices::getInstance()
50            ->getRevisionLookup()
51            ->getRevisionById( $revid );
52        if ( !$revRecord ) {
53            $this->dieWithError( [ 'apierror-nosuchrevid', $revid ], 'notarget' );
54        }
55
56        $linkTarget = $revRecord->getPageAsLinkTarget();
57        if ( $this->getPermissionManager()->isBlockedFrom( $this->getUser(), $linkTarget, false ) ) {
58            // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Guaranteed via isBlockedFrom() above
59            $this->dieBlocked( $this->getUser()->getBlock() );
60        }
61
62        $title = Title::newFromLinkTarget( $linkTarget );
63
64        // Construct submit form...
65        $form = new RevisionReviewForm( $this->getUser() );
66        $form->setTitle( $title );
67        $form->setOldId( $revid );
68        $form->setAction( $params['unapprove'] ?
69            RevisionReviewForm::ACTION_UNAPPROVE :
70            RevisionReviewForm::ACTION_APPROVE );
71        if ( isset( $params['comment'] ) ) {
72            $form->setComment( $params['comment'] );
73        }
74        // The flagging parameter has the form 'flag_$name' ($name varies
75        // by wiki). Extract it and put the value into $form->tag.
76        $form->setTag( FlaggedRevs::binaryFlagging() ?
77            1 :
78            (int)$params['flag_' . FlaggedRevs::getTagName() ]
79        );
80        if ( $form->getAction() === RevisionReviewForm::ACTION_APPROVE ) {
81            $form->bypassValidationKey(); // always OK; uses current templates
82        }
83
84        $form->ready(); // all params set
85
86        # Try to do the actual review
87        $status = $form->submit();
88        # Approve/de-approve success
89        if ( $status === true ) {
90            $this->getResult()->addValue(
91                null, $this->getModuleName(), [ 'result' => 'Success' ] );
92        # Generic failures
93        } elseif ( $status === 'review_page_notexists' ) {
94            $this->dieWithError( 'apierror-flaggedrevs-pagedoesnotexist', 'notarget' );
95        } elseif ( $status === 'review_page_unreviewable' ) {
96            $this->dieWithError( 'apierror-flaggedrevs-notreviewable', 'notreviewable' );
97        # Approve-specific failures
98        } elseif ( $form->getAction() === RevisionReviewForm::ACTION_APPROVE ) {
99            if ( $status === 'review_denied' ) {
100                $this->dieWithError( 'apierror-flaggedrevs-cantreview', 'permissiondenied' );
101            } elseif ( $status === 'review_too_low' ) {
102                $this->dieWithError( 'apierror-flaggedrevs-toolow', 'mixedapproval' );
103            } elseif ( $status === 'review_bad_key' ) {
104                $this->dieWithError( 'apierror-flaggedrevs-cantreview', 'permissiondenied' );
105            } elseif ( $status === 'review_bad_tags' ) {
106                $this->dieWithError( 'apierror-flaggedrevs-badflags', 'invalidtags' );
107            } elseif ( $status === 'review_bad_oldid' ) {
108                $this->dieWithError( [ 'apierror-nosuchrevid', $revid ], 'notarget' );
109            } else {
110                // FIXME: review_param_missing? better msg?
111                $this->dieWithError( [ 'apierror-unknownerror-nocode' ], 'unknownerror' );
112            }
113        # De-approve specific failure
114        } elseif ( $form->getAction() === RevisionReviewForm::ACTION_UNAPPROVE ) {
115            if ( $status === 'review_denied' ) {
116                $this->dieWithError( 'apierror-flaggedrevs-cantunreview', 'permissiondenied' );
117            } elseif ( $status === 'review_not_flagged' ) {
118                $this->dieWithError( 'apierror-flaggedrevs-noflaggedrev', 'notarget' );
119            } else {
120                // FIXME: review_param_missing? better msg?
121                $this->dieWithError( [ 'apierror-unknownerror-nocode' ], 'unknownerror' );
122            }
123        }
124    }
125
126    /**
127     * @inheritDoc
128     */
129    public function isWriteMode() {
130        return true;
131    }
132
133    /**
134     * @inheritDoc
135     */
136    protected function getAllowedParams() {
137        $pars = [
138            'revid' => null,
139            'comment' => null,
140            'unapprove' => false
141        ];
142        if ( !FlaggedRevs::binaryFlagging() && !FlaggedRevs::useOnlyIfProtected() ) {
143            $strLevels = array_map( 'strval', range( 0, FlaggedRevs::getMaxLevel() ) );
144            $pars['flag_' . FlaggedRevs::getTagName()] = [
145                ParamValidator::PARAM_DEFAULT => '1', // default
146                ParamValidator::PARAM_TYPE => $strLevels, // array of allowed values
147                ApiBase::PARAM_HELP_MSG => [ 'apihelp-review-param-flag', FlaggedRevs::getTagName() ],
148            ];
149        }
150        return $pars;
151    }
152
153    /**
154     * @return string
155     */
156    public function needsToken() {
157        return 'csrf';
158    }
159
160    /**
161     * @inheritDoc
162     */
163    protected function getExamplesMessages() {
164        return [
165            'action=review&revid=12345&token=123AB&flag_accuracy=1&comment=Ok'
166                => 'apihelp-review-example-1',
167        ];
168    }
169}