Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
19.70% covered (danger)
19.70%
13 / 66
33.33% covered (danger)
33.33%
2 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApprovalBallot
19.70% covered (danger)
19.70%
13 / 66
33.33% covered (danger)
33.33%
2 / 6
166.66
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
 getQuestionForm
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
6
 submitQuestion
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 packRecord
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 unpackRecord
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 convertScores
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3namespace MediaWiki\Extension\SecurePoll\Ballots;
4
5use MediaWiki\Extension\SecurePoll\Entities\Option;
6use MediaWiki\Extension\SecurePoll\Entities\Question;
7use OOUI\CheckboxInputWidget;
8use OOUI\FieldLayout;
9use OOUI\FieldsetLayout;
10use OOUI\HtmlSnippet;
11
12/**
13 * Checkbox approval voting.
14 */
15class ApprovalBallot extends Ballot {
16    /** @inheritDoc */
17    public static function getTallyTypes() {
18        return [ 'plurality' ];
19    }
20
21    /**
22     * @param Question $question
23     * @param array $options
24     * @return FieldsetLayout
25     */
26    public function getQuestionForm( $question, $options ) {
27        $name = 'securepoll_q' . $question->getId();
28
29        $fieldset = new FieldsetLayout( [
30            'classes' => [ 'securepoll-option-approval ' ]
31        ] );
32
33        foreach ( $options as $option ) {
34            $optionHTML = $option->parseMessageInline( 'text' );
35            $optionId = $option->getId();
36            $inputId = "{$name}_opt{$optionId}";
37
38            $fieldset->addItems( [
39                new FieldLayout( new CheckboxInputWidget( [
40                    'name' => $inputId,
41                    'selected' => $this->getRequest()->getBool( $inputId ),
42                    'value' => 1
43                ] ), [
44                    'label' => new HtmlSnippet( $optionHTML ),
45                    'align' => 'inline'
46                ] )
47            ] );
48        }
49
50        return $fieldset;
51    }
52
53    /**
54     * @param Question $question
55     * @param BallotStatus $status
56     * @return string
57     */
58    public function submitQuestion( $question, $status ) {
59        $options = $question->getOptions();
60        $record = '';
61        foreach ( $options as $option ) {
62            $id = 'securepoll_q' . $question->getId() . '_opt' . $option->getId();
63            $checked = $this->getRequest()->getBool( $id );
64            $record .= $this->packRecord( $question, $option, $checked );
65        }
66
67        return $record;
68    }
69
70    /**
71     * @param Question $question
72     * @param Option $option
73     * @param bool $checked
74     * @return string
75     */
76    public function packRecord( $question, $option, $checked ) {
77        return sprintf(
78            'Q%08X-A%08X-%s--',
79            $question->getId(),
80            $option->getId(),
81            $checked ? 'y' : 'n'
82        );
83    }
84
85    /** @inheritDoc */
86    public function unpackRecord( $record ) {
87        $scores = [];
88        $itemLength = 2 * 8 + 7;
89        for ( $offset = 0, $len = strlen( $record ); $offset < $len; $offset += $itemLength ) {
90            if ( !preg_match(
91                '/Q([0-9A-F]{8})-A([0-9A-F]{8})-([yn])--/A',
92                $record,
93                $m,
94                0,
95                $offset
96            )
97            ) {
98                wfDebug( __METHOD__ . ": regex doesn't match\n" );
99
100                return false;
101            }
102            $qid = intval( base_convert( $m[1], 16, 10 ) );
103            $oid = intval( base_convert( $m[2], 16, 10 ) );
104            $score = ( $m[3] === 'y' ) ? 1 : 0;
105            $scores[$qid][$oid] = $score;
106        }
107
108        return $scores;
109    }
110
111    /** @inheritDoc */
112    public function convertScores( $scores, $params = [] ) {
113        $result = [];
114        foreach ( $this->election->getQuestions() as $question ) {
115            $qid = $question->getId();
116            if ( !isset( $scores[$qid] ) ) {
117                return false;
118            }
119            $s = '';
120            $qscores = $scores[$qid];
121            ksort( $qscores );
122            $first = true;
123            foreach ( $qscores as $score ) {
124                if ( $first ) {
125                    $first = false;
126                } else {
127                    $s .= ', ';
128                }
129                $s .= $score ? 'y' : 'n';
130            }
131            $result[$qid] = $s;
132        }
133
134        return $result;
135    }
136
137}