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