/** * Execute the subpage. * @param $params array Array of subpage parameters. */ function execute( $params ) { global $wgOut, $wgUser, $wgLang; if ( !count( $params ) ) { $wgOut->addWikiMsg( 'securepoll-too-few-params' ); return; } $this->voteId = intval( $params[0] ); $db = $this->context->getDB(); $row = $db->selectRow( array( 'securepoll_votes', 'securepoll_elections', 'securepoll_voters' ), '*', array( 'vote_id' => $this->voteId, 'vote_election=el_entity', 'vote_voter=voter_id', ), __METHOD__ ); if ( !$row ) { $wgOut->addWikiMsg( 'securepoll-invalid-vote', $this->voteId ); return; } $this->election = $this->context->newElectionFromRow( $row ); $this->initLanguage( $wgUser, $this->election ); $this->parent->setSubtitle( array( $this->parent->getTitle( 'list/' . $this->election->getId() ), wfMsg( 'securepoll-list-title', $this->election->getMessage( 'title' ) ) ) ); if ( !$this->election->isAdmin( $wgUser ) ) { $wgOut->addWikiMsg( 'securepoll-need-admin' ); return; } # Show vote properties $wgOut->setPageTitle( wfMsg( 'securepoll-details-title', $this->voteId ) ); $wgOut->addHTML( '<table class="mw-datatable TablePager">' . $this->detailEntry( 'securepoll-header-id', $row->vote_id ) . $this->detailEntry( 'securepoll-header-timestamp', $row->vote_timestamp ) . $this->detailEntry( 'securepoll-header-voter-name', $row->voter_name ) . $this->detailEntry( 'securepoll-header-voter-type', $row->voter_type ) . $this->detailEntry( 'securepoll-header-voter-domain', $row->voter_domain ) . $this->detailEntry( 'securepoll-header-url', $row->voter_url ) . $this->detailEntry( 'securepoll-header-ip', IP::formatHex( $row->vote_ip ) ) . $this->detailEntry( 'securepoll-header-xff', $row->vote_xff ) . $this->detailEntry( 'securepoll-header-ua', $row->vote_ua ) . $this->detailEntry( 'securepoll-header-token-match', $row->vote_token_match ) . '</table>' ); # Show voter properties $wgOut->addHTML( '<h2>' . wfMsgHTML( 'securepoll-voter-properties' ) . "</h2>\n" ); $wgOut->addHTML( '<table class="mw-datatable TablePager">' ); $props = SecurePoll_Voter::decodeProperties( $row->voter_properties ); foreach ( $props as $name => $value ) { if ( is_array( $value ) ) { $value = implode( ', ', $value ); } $wgOut->addHTML( '<td class="securepoll-detail-header">' . htmlspecialchars( $name ) . "</td>\n" . '<td>' . htmlspecialchars( $value ) . "</td></tr>\n" ); } $wgOut->addHTML( '</table>' ); # Show cookie dups $cmTable = $db->tableName( 'securepoll_cookie_match' ); $voterId = intval( $row->voter_id ); $sql = "(SELECT cm_voter_2 as voter, cm_timestamp FROM $cmTable WHERE cm_voter_1=$voterId)" . " UNION " . "(SELECT cm_voter_1 as voter, cm_timestamp FROM $cmTable WHERE cm_voter_2=$voterId)"; $res = $db->query( $sql, __METHOD__ ); if ( $res->numRows() ) { $wgOut->addHTML( '<h2>' . wfMsgHTML( 'securepoll-cookie-dup-list' ) . '</h2>' ); $wgOut->addHTML( '<table class="mw-datatable TablePager">' ); foreach ( $res as $row ) { $voter = $this->context->getVoter( $row->voter ); $wgOut->addHTML( '<tr>' . '<td>' . htmlspecialchars( $wgLang->timeanddate( $row->cm_timestamp ) ) . '</td>' . '<td>' . Xml::element( 'a', array( 'href' => $voter->getUrl() ), $voter->getName() . '@' . $voter->getDomain() ) . '</td></tr>' ); } $wgOut->addHTML( '</table>' ); } # Show strike log $wgOut->addHTML( '<h2>' . wfMsgHTML( 'securepoll-strike-log' ) . "</h2>\n" ); $pager = new SecurePoll_StrikePager( $this, $this->voteId ); $wgOut->addHTML( $pager->getBody() . $pager->getNavigationBar() ); }