Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
65.31% |
32 / 49 |
|
33.33% |
1 / 3 |
CRAP | |
0.00% |
0 / 1 |
DumpPage | |
65.31% |
32 / 49 |
|
33.33% |
1 / 3 |
24.40 | |
0.00% |
0 / 1 |
execute | |
57.14% |
20 / 35 |
|
0.00% |
0 / 1 |
17.87 | |||
sendHeaders | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getFormatFromRequest | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
4.25 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\SecurePoll\Pages; |
4 | |
5 | use Exception; |
6 | use InvalidArgumentException; |
7 | use MediaWiki\Extension\SecurePoll\DumpElection; |
8 | |
9 | /** |
10 | * Special:SecurePoll subpage for exporting encrypted election records. |
11 | */ |
12 | class DumpPage extends ActionPage { |
13 | |
14 | /** |
15 | * Execute the subpage. |
16 | * |
17 | * @param array $params Array of subpage parameters. |
18 | * |
19 | * @throws InvalidArgumentException |
20 | */ |
21 | public function execute( $params ) { |
22 | $out = $this->specialPage->getOutput(); |
23 | |
24 | if ( !count( $params ) ) { |
25 | $out->addWikiMsg( 'securepoll-too-few-params' ); |
26 | |
27 | return; |
28 | } |
29 | |
30 | $electionId = intval( $params[0] ); |
31 | $format = $this->getFormatFromRequest(); |
32 | |
33 | $this->election = $this->context->getElection( $electionId ); |
34 | if ( !$this->election ) { |
35 | $out->addWikiMsg( 'securepoll-invalid-election', $electionId ); |
36 | |
37 | return; |
38 | } |
39 | $this->initLanguage( $this->specialPage->getUser(), $this->election ); |
40 | |
41 | $out->setPageTitleMsg( $this->msg( 'securepoll-dump-title', $this->election->getMessage( 'title' ) ) ); |
42 | |
43 | if ( !$this->election->isFinished() ) { |
44 | $out->addWikiMsg( |
45 | 'securepoll-dump-not-finished', |
46 | $this->specialPage->getLanguage()->date( $this->election->getEndDate() ), |
47 | $this->specialPage->getLanguage()->time( $this->election->getEndDate() ) |
48 | ); |
49 | |
50 | return; |
51 | } |
52 | |
53 | $isAdmin = $this->election->isAdmin( $this->specialPage->getAuthority() ); |
54 | if ( $this->election->getProperty( 'voter-privacy' ) && !$isAdmin ) { |
55 | $out->addWikiMsg( 'securepoll-dump-private' ); |
56 | |
57 | return; |
58 | } |
59 | |
60 | $dbr = $this->context->getDB( DB_REPLICA ); |
61 | if ( !$isAdmin && !$this->election->getTallyResultTimeFromDb( $dbr ) ) { |
62 | $out->addWikiMsg( 'securepoll-dump-not-tallied' ); |
63 | |
64 | return; |
65 | } |
66 | |
67 | try { |
68 | if ( $format === "blt" ) { |
69 | $dump = DumpElection::createBLTDump( $this->election ); |
70 | } else { |
71 | $dump = DumpElection::createXMLDump( $this->election ); |
72 | } |
73 | } catch ( Exception $e ) { |
74 | $out->addWikiTextAsInterface( $e->getMessage() ); |
75 | |
76 | return; |
77 | } |
78 | |
79 | $this->sendHeaders(); |
80 | echo $dump; |
81 | } |
82 | |
83 | public function sendHeaders() { |
84 | $this->specialPage->getOutput()->disable(); |
85 | header( 'Content-Type: application/vnd.mediawiki.securepoll' ); |
86 | $electionId = $this->election->getId(); |
87 | $filename = urlencode( "$electionId-" . wfTimestampNow() . '.securepoll' ); |
88 | header( "Content-Disposition: attachment; filename=$filename" ); |
89 | $this->context->setLanguages( [ $this->election->getLanguage() ] ); |
90 | } |
91 | |
92 | /** |
93 | * Valid formats are |
94 | * - xml |
95 | * - blt |
96 | * |
97 | * Default is xml |
98 | * |
99 | * @return string |
100 | * @throws InvalidArgumentException |
101 | */ |
102 | private function getFormatFromRequest(): string { |
103 | $request = $this->specialPage->getRequest(); |
104 | $queryParams = $request->getQueryValues(); |
105 | |
106 | if ( empty( $queryParams['format'] ) ) { |
107 | return "xml"; |
108 | } |
109 | |
110 | $format = $queryParams['format']; |
111 | if ( $format !== "xml" && $format !== "blt" ) { |
112 | throw new InvalidArgumentException( "Invalid format" ); |
113 | } |
114 | |
115 | return $format; |
116 | } |
117 | } |