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