Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 115
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SecurePollContentHandler
0.00% covered (danger)
0.00%
0 / 115
0.00% covered (danger)
0.00%
0 / 6
870
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDataFromElection
0.00% covered (danger)
0.00%
0 / 88
0.00% covered (danger)
0.00%
0 / 1
506
 makeContentFromElection
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 canBeUsedOn
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getActionOverrides
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
 getContentClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\SecurePoll;
4
5use ContentHandler;
6use FormatJson;
7use JsonContentHandler;
8use MediaWiki\Extension\SecurePoll\Entities\Election;
9use MediaWiki\Extension\SecurePoll\Exceptions\InvalidDataException;
10use MediaWiki\Title\Title;
11
12/**
13 * SecurePoll Content Handler
14 *
15 * @file
16 * @ingroup Extensions
17 * @ingroup SecurePoll
18 *
19 * @author Brad Jorsch <bjorsch@wikimedia.org>
20 */
21class SecurePollContentHandler extends JsonContentHandler {
22    public function __construct( $modelId = 'SecurePoll' ) {
23        parent::__construct( $modelId );
24    }
25
26    /**
27     * Load data from an election as a PHP array structure
28     *
29     * @param Election $election
30     * @param string $subpage Subpage to get content for
31     * @param bool $useExclusion
32     * @return array
33     */
34    public static function getDataFromElection(
35        Election $election,
36        $subpage = '',
37        $useExclusion = false
38    ) {
39        if ( $subpage === '' ) {
40            $properties = $election->getAllProperties();
41            if ( $useExclusion ) {
42                $excludedNames = array_flip( $election->getPropertyDumpExclusion() ) + [
43                    'gpg-encrypt-key' => true,
44                    'gpg-sign-key' => true,
45                    'gpg-decrypt-key' => true,
46                ];
47
48                foreach ( $properties as $k => $v ) {
49                    if ( isset( $excludedNames[$k] ) ) {
50                        $properties[$k] = '<redacted>';
51                    }
52                }
53                unset(
54                    $properties['list_job-key'],
55                    $properties['list_total-count'],
56                    $properties['list_complete-count']
57                );
58            }
59            $data = [
60                'id' => $election->getId(),
61                'title' => $election->title,
62                'ballot' => $election->ballotType,
63                'tally' => $election->tallyType,
64                'lang' => $election->getLanguage(),
65                'startDate' => wfTimestamp( TS_ISO_8601, $election->getStartDate() ),
66                'endDate' => wfTimestamp( TS_ISO_8601, $election->getEndDate() ),
67                'authType' => $election->authType,
68                'properties' => $properties,
69                'questions' => [],
70            ];
71
72            foreach ( $election->getQuestions() as $question ) {
73                $properties = $question->getAllProperties();
74                if ( $useExclusion ) {
75                    $excludedNames = array_flip( $question->getPropertyDumpExclusion() );
76                    foreach ( $properties as $k => $v ) {
77                        if ( isset( $excludedNames[$k] ) ) {
78                            $properties[$k] = '<redacted>';
79                        }
80                    }
81                }
82                $q = [
83                    'id' => $question->getId(),
84                    'properties' => $properties,
85                    'options' => [],
86                ];
87
88                foreach ( $question->getOptions() as $option ) {
89                    $properties = $option->getAllProperties();
90                    if ( $useExclusion ) {
91                        $excludedNames = array_flip( $option->getPropertyDumpExclusion() );
92                        foreach ( $properties as $k => $v ) {
93                            if ( isset( $excludedNames[$k] ) ) {
94                                $properties[$k] = '<redacted>';
95                            }
96                        }
97                    }
98                    $o = [
99                        'id' => $option->getId(),
100                        'properties' => $properties,
101                    ];
102                    $q['options'][] = $o;
103                }
104
105                $data['questions'][] = $q;
106            }
107        } elseif ( preg_match( '#^msg/(\S+)$#', $subpage, $m ) ) {
108            $lang = $m[1];
109            $data = [
110                'id' => $election->getId(),
111                'lang' => $lang,
112                'messages' => [],
113                'questions' => [],
114            ];
115            foreach ( $election->getMessageNames() as $name ) {
116                $value = $election->getRawMessage( $name, $lang );
117                if ( $value !== false ) {
118                    $data['messages'][$name] = $value;
119                }
120            }
121
122            foreach ( $election->getQuestions() as $question ) {
123                $q = [
124                    'id' => $question->getId(),
125                    'messages' => [],
126                    'options' => [],
127                ];
128                foreach ( $question->getMessageNames() as $name ) {
129                    $value = $question->getRawMessage( $name, $lang );
130                    if ( $value !== false ) {
131                        $q['messages'][$name] = $value;
132                    }
133                }
134
135                foreach ( $question->getOptions() as $option ) {
136                    $o = [
137                        'id' => $option->getId(),
138                        'messages' => [],
139                    ];
140                    foreach ( $option->getMessageNames() as $name ) {
141                        $value = $option->getRawMessage( $name, $lang );
142                        if ( $value !== false ) {
143                            $o['messages'][$name] = $value;
144                        }
145                    }
146                    $q['options'][] = $o;
147                }
148
149                $data['questions'][] = $q;
150            }
151        } else {
152            throw new InvalidDataException( __METHOD__ . ': Unsupported subpage format' );
153        }
154
155        return $data;
156    }
157
158    /**
159     * Create a SecurePollContent for an election
160     *
161     * @param Election $election
162     * @param string $subpage Subpage to get content for
163     * @return array ( Title, SecurePollContent )
164     */
165    public static function makeContentFromElection( Election $election, $subpage = '' ) {
166        $json = FormatJson::encode(
167            self::getDataFromElection( $election, $subpage, true ),
168            false,
169            FormatJson::ALL_OK
170        );
171        $title = Title::makeTitle(
172            NS_SECUREPOLL,
173            $election->getId() . ( $subpage === '' ? '' : "/$subpage" )
174        );
175
176        return [
177            $title,
178            ContentHandler::makeContent( $json, $title, 'SecurePoll' )
179        ];
180    }
181
182    public function canBeUsedOn( Title $title ) {
183        global $wgSecurePollUseNamespace;
184
185        return $wgSecurePollUseNamespace && $title->getNamespace() == NS_SECUREPOLL;
186    }
187
188    public function getActionOverrides() {
189        // Disable write actions
190        return [
191            'delete' => false,
192            'edit' => false,
193            'info' => false,
194            'protect' => false,
195            'revert' => false,
196            'rollback' => false,
197            'submit' => false,
198            'unprotect' => false,
199        ];
200    }
201
202    protected function getContentClass() {
203        return SecurePollContent::class;
204    }
205}