Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiStrikeVote
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 7
110
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 / 36
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
 needsToken
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 / 18
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 *
4 *
5 * Created on Jul 7, 2015
6 *
7 * Copyright © 2015 Frances Hocutt "<Firstinitial><Lastname>@wikimedia.org"
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 *
24 * @file
25 */
26
27namespace MediaWiki\Extension\SecurePoll\Api;
28
29use MediaWiki\Api\ApiBase;
30use MediaWiki\Api\ApiMain;
31use MediaWiki\Extension\SecurePoll\ActionPageFactory;
32use MediaWiki\Extension\SecurePoll\SpecialSecurePoll;
33use Wikimedia\ParamValidator\ParamValidator;
34
35/**
36 * API module to facilitate striking/unstriking SecurePoll votes.
37 *
38 * @ingroup API
39 */
40class ApiStrikeVote extends ApiBase {
41    private ActionPageFactory $actionPageFactory;
42
43    public function __construct(
44        ApiMain $apiMain,
45        string $moduleName,
46        ActionPageFactory $actionPageFactory
47    ) {
48        parent::__construct( $apiMain, $moduleName );
49        $this->actionPageFactory = $actionPageFactory;
50    }
51
52    /**
53     * Strike or unstrike a vote.
54     */
55    public function execute() {
56        $params = $this->extractRequestParams();
57        $option = $params['option'];
58        $voteid = $params['voteid'];
59        $reason = $params['reason'];
60
61        // FIXME: thoughts on whether error checks should go here or in strike()?
62        // if not logged in: fail
63        $user = $this->getUser();
64        if ( !$user->isNamed() ) {
65            $this->dieWithError(
66                'apierror-securepoll-mustbeloggedin-strikevote',
67                'notloggedin'
68            );
69        }
70
71        // see if vote exists
72        // (using SpecialPageFactory gets us bad type hints for phan here)
73        $page = new SpecialSecurePoll( $this->actionPageFactory );
74        $context = $page->sp_context;
75        $db = $context->getDB();
76        $row = $db->newSelectQueryBuilder()
77            ->select( 'elections.*' )
78            ->from( 'securepoll_votes' )
79            ->join( 'securepoll_elections', 'elections', 'vote_election=el_entity' )
80            ->where( [ 'vote_id' => $voteid ] )
81            ->caller( __METHOD__ )
82            ->fetchRow();
83
84        // if no vote: fail
85        if ( !$row ) {
86            $this->dieWithError(
87                [
88                    'apierror-securepoll-badvoteid',
89                    $voteid
90                ],
91                'novote'
92            );
93        }
94
95        // strike the vote
96        $subpage = $page->getSubpage( 'list' );
97        $subpage->election = $context->newElectionFromRow( $row );
98        // @phan-suppress-next-line PhanUndeclaredMethod
99        $status = $subpage->strike( $option, $voteid, $reason );
100
101        $result = [];
102        if ( $status->isGood() ) {
103            $result['status'] = 'good';
104        } else {
105            $this->dieStatus( $status );
106        }
107        $this->getResult()->addValue( null, $this->getModuleName(), $result );
108    }
109
110    public function mustBePosted() {
111        return true;
112    }
113
114    public function isWriteMode() {
115        return true;
116    }
117
118    public function needsToken() {
119        return 'csrf';
120    }
121
122    protected function getAllowedParams() {
123        return [
124            'option' => [
125                ParamValidator::PARAM_TYPE => [
126                    'strike',
127                    'unstrike'
128                ],
129                ParamValidator::PARAM_REQUIRED => true,
130                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
131            ],
132            'reason' => [
133                ParamValidator::PARAM_TYPE => 'string',
134                ParamValidator::PARAM_REQUIRED => true,
135            ],
136            'voteid' => [
137                ParamValidator::PARAM_TYPE => 'integer',
138                ParamValidator::PARAM_REQUIRED => true,
139            ],
140        ];
141    }
142
143    protected function getExamplesMessages() {
144        return [
145            'action=strikevote&option=strike&reason=duplication&voteid=1&token=123ABC' =>
146                'apihelp-strikevote-example-strike',
147            'action=strikevote&option=unstrike&reason=mistake&voteid=1&token=123ABC' =>
148                'apihelp-strikevote-example-unstrike',
149        ];
150    }
151}