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 ApiBase;
30use 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    /** @var ActionPageFactory */
42    private $actionPageFactory;
43
44    /**
45     * @param ApiMain $apiMain
46     * @param string $moduleName
47     * @param ActionPageFactory $actionPageFactory
48     */
49    public function __construct(
50        ApiMain $apiMain,
51        $moduleName,
52        ActionPageFactory $actionPageFactory
53    ) {
54        parent::__construct( $apiMain, $moduleName );
55        $this->actionPageFactory = $actionPageFactory;
56    }
57
58    /**
59     * Strike or unstrike a vote.
60     */
61    public function execute() {
62        $params = $this->extractRequestParams();
63        $option = $params['option'];
64        $voteid = $params['voteid'];
65        $reason = $params['reason'];
66
67        // FIXME: thoughts on whether error checks should go here or in strike()?
68        // if not logged in: fail
69        $user = $this->getUser();
70        if ( !$user->isNamed() ) {
71            $this->dieWithError(
72                'apierror-securepoll-mustbeloggedin-strikevote',
73                'notloggedin'
74            );
75        }
76
77        // see if vote exists
78        // (using SpecialPageFactory gets us bad type hints for phan here)
79        $page = new SpecialSecurePoll( $this->actionPageFactory );
80        $context = $page->sp_context;
81        $db = $context->getDB();
82        $row = $db->newSelectQueryBuilder()
83            ->select( 'elections.*' )
84            ->from( 'securepoll_votes' )
85            ->join( 'securepoll_elections', 'elections', 'vote_election=el_entity' )
86            ->where( [ 'vote_id' => $voteid ] )
87            ->caller( __METHOD__ )
88            ->fetchRow();
89
90        // if no vote: fail
91        if ( !$row ) {
92            $this->dieWithError(
93                [
94                    'apierror-securepoll-badvoteid',
95                    $voteid
96                ],
97                'novote'
98            );
99        }
100
101        // strike the vote
102        $subpage = $page->getSubpage( 'list' );
103        $subpage->election = $context->newElectionFromRow( $row );
104        // @phan-suppress-next-line PhanUndeclaredMethod
105        $status = $subpage->strike( $option, $voteid, $reason );
106
107        $result = [];
108        if ( $status->isGood() ) {
109            $result['status'] = 'good';
110        } else {
111            $this->dieStatus( $status );
112        }
113        $this->getResult()->addValue( null, $this->getModuleName(), $result );
114    }
115
116    public function mustBePosted() {
117        return true;
118    }
119
120    public function isWriteMode() {
121        return true;
122    }
123
124    public function needsToken() {
125        return 'csrf';
126    }
127
128    protected function getAllowedParams() {
129        return [
130            'option' => [
131                ParamValidator::PARAM_TYPE => [
132                    'strike',
133                    'unstrike'
134                ],
135                ParamValidator::PARAM_REQUIRED => true,
136                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
137            ],
138            'reason' => [
139                ParamValidator::PARAM_TYPE => 'string',
140                ParamValidator::PARAM_REQUIRED => true,
141            ],
142            'voteid' => [
143                ParamValidator::PARAM_TYPE => 'integer',
144                ParamValidator::PARAM_REQUIRED => true,
145            ],
146        ];
147    }
148
149    protected function getExamplesMessages() {
150        return [
151            'action=strikevote&option=strike&reason=duplication&voteid=1&token=123ABC' =>
152                'apihelp-strikevote-example-strike',
153            'action=strikevote&option=unstrike&reason=mistake&voteid=1&token=123ABC' =>
154                'apihelp-strikevote-example-unstrike',
155        ];
156    }
157}