Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
9.43% covered (danger)
9.43%
5 / 53
28.57% covered (danger)
28.57%
2 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ChooseBallot
9.43% covered (danger)
9.43%
5 / 53
28.57% covered (danger)
28.57%
2 / 7
159.60
0.00% covered (danger)
0.00%
0 / 1
 getTallyTypes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCreateDescriptors
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getQuestionForm
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
6
 submitQuestion
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 packRecord
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 unpackRecord
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 convertScores
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\Extension\SecurePoll\Ballots;
4
5use MediaWiki\Extension\SecurePoll\Entities\Question;
6use OOUI\FieldLayout;
7use OOUI\FieldsetLayout;
8use OOUI\HtmlSnippet;
9use OOUI\RadioInputWidget;
10
11/**
12 * A ballot class which asks the user to choose one answer only from the
13 * given options, for each question.
14 */
15class ChooseBallot extends Ballot {
16    /**
17     * Get a list of names of tallying methods, which may be used to produce a
18     * result from this ballot type.
19     * @return array
20     */
21    public static function getTallyTypes() {
22        return [ 'plurality' ];
23    }
24
25    /** @inheritDoc */
26    public static function getCreateDescriptors() {
27        $ret = parent::getCreateDescriptors();
28        $ret['option'] += [
29            'name' => [
30                'label-message' => 'securepoll-create-label-option-name',
31                'type' => 'text',
32                'SecurePoll_type' => 'message',
33            ],
34        ];
35
36        return $ret;
37    }
38
39    /**
40     * Get the HTML form segment for a single question
41     * @param Question $question
42     * @param array $options Array of options, in the order they should be displayed
43     * @return FieldsetLayout
44     */
45    public function getQuestionForm( $question, $options ) {
46        $name = 'securepoll_q' . $question->getId();
47        $fieldset = new FieldsetLayout();
48        foreach ( $options as $option ) {
49            $optionHTML = $option->parseMessageInline( 'text' );
50            $optionId = $option->getId();
51
52            $fieldset->appendContent( [
53                new FieldLayout( new RadioInputWidget( [
54                    'name' => $name,
55                    'value' => $optionId,
56                    'required' => true,
57                    ] ), [
58                        'classes' => [ 'securepoll-option-choose' ],
59                        'label' => new HtmlSnippet( $optionHTML ),
60                        'align' => 'inline'
61                    ] )
62            ] );
63        }
64
65        return $fieldset;
66    }
67
68    /**
69     * @param Question $question
70     * @param BallotStatus $status
71     * @return string
72     */
73    public function submitQuestion( $question, $status ) {
74        $result = $this->getRequest()->getInt( 'securepoll_q' . $question->getId() );
75        if ( !$result ) {
76            $status->fatal( 'securepoll-unanswered-questions' );
77        } else {
78            return $this->packRecord( $question->getId(), $result );
79        }
80    }
81
82    /**
83     * @param int $qid
84     * @param int $oid
85     * @return string
86     */
87    public function packRecord( $qid, $oid ) {
88        return sprintf( 'Q%08XA%08X', $qid, $oid );
89    }
90
91    /** @inheritDoc */
92    public function unpackRecord( $record ) {
93        $result = [];
94        $record = trim( $record );
95        for ( $offset = 0, $len = strlen( $record ); $offset < $len; $offset += 18 ) {
96            if ( !preg_match( '/Q([0-9A-F]{8})A([0-9A-F]{8})/A', $record, $m, 0, $offset ) ) {
97                wfDebug( __METHOD__ . ": regex doesn't match\n" );
98
99                return false;
100            }
101            $qid = intval( base_convert( $m[1], 16, 10 ) );
102            $oid = intval( base_convert( $m[2], 16, 10 ) );
103            $result[$qid] = [ $oid => 1 ];
104        }
105
106        return $result;
107    }
108
109    /** @inheritDoc */
110    public function convertScores( $scores, $params = [] ) {
111        $s = '';
112        foreach ( $this->election->getQuestions() as $question ) {
113            $qid = $question->getId();
114            if ( !isset( $scores[$qid] ) ) {
115                return false;
116            }
117            if ( $s !== '' ) {
118                $s .= '; ';
119            }
120            $oid = key( $scores );
121            // FIXME: getOption doesn't exist
122            // @phan-suppress-next-line PhanUndeclaredMethod
123            $option = $this->election->getOption( $oid );
124            $s .= $option->getMessage( 'name' );
125        }
126
127        return $s;
128    }
129}