Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
65.31% covered (warning)
65.31%
32 / 49
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
DumpPage
65.31% covered (warning)
65.31%
32 / 49
33.33% covered (danger)
33.33%
1 / 3
24.40
0.00% covered (danger)
0.00%
0 / 1
 execute
57.14% covered (warning)
57.14%
20 / 35
0.00% covered (danger)
0.00%
0 / 1
17.87
 sendHeaders
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getFormatFromRequest
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
1<?php
2
3namespace MediaWiki\Extension\SecurePoll\Pages;
4
5use Exception;
6use InvalidArgumentException;
7use MediaWiki\Extension\SecurePoll\DumpElection;
8
9/**
10 * Special:SecurePoll subpage for exporting encrypted election records.
11 */
12class 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}