Skip to content

Commit

Permalink
Polls
Browse files Browse the repository at this point in the history
Using a lot of code from the previous iteration of statbus
  • Loading branch information
nfreader committed May 7, 2019
1 parent 511d707 commit 3dbd481
Show file tree
Hide file tree
Showing 10 changed files with 332 additions and 0 deletions.
111 changes: 111 additions & 0 deletions src/Statbus/Controllers/PollController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

namespace Statbus\Controllers;

use Psr\Container\ContainerInterface;
use Statbus\Controllers\Controller as Controller;
use Statbus\Models\Poll as Poll;

class PollController Extends Controller {

public function __construct(ContainerInterface $container) {
parent::__construct($container);
$this->pages = ceil($this->DB->cell("SELECT count(tbl_poll_question.id) FROM tbl_poll_question WHERE tbl_poll_question.adminonly != 1
AND tbl_poll_question.dontshow IS NULL") / $this->per_page);

$this->pollModel = new Poll();
$this->breadcrumbs['Polls'] = $this->router->pathFor('poll.index');

}

public function index($request, $response, $args){
if(isset($args['page'])) {
$this->page = filter_var($args['page'], FILTER_VALIDATE_INT);
}
$polls = $this->DB->run("SELECT P.*,
SEC_TO_TIME(TIMESTAMPDIFF(SECOND, P.starttime, P.endtime)) AS duration,
IF(P.endtime < NOW(), 1, 0) AS ended,
count(tbl_poll_vote.id) + count(tbl_poll_textreply.id) as totalVotes
FROM tbl_poll_question P
LEFT JOIN tbl_poll_vote ON P.id = tbl_poll_vote.pollid
LEFT JOIN tbl_poll_textreply ON P.id = tbl_poll_textreply.pollid
WHERE (P.dontshow = 0 OR P.dontshow = 1 AND P.endtime < NOW())
AND P.adminonly = 0
GROUP BY P.id
ORDER BY P.id DESC
LIMIT ?,?", ($this->page * $this->per_page) - $this->per_page, $this->per_page);
foreach($polls as &$p){
$p = $this->pollModel->parsePoll($p);
}
return $this->view->render($response, 'polls/listing.tpl',[
'polls' => $polls,
'poll' => $this,
'breadcrumbs' => $this->breadcrumbs
]);
}

public function single($request, $response, $args) {
$poll = $this->getPoll($args['id']);
$url = parent::getFullURL($this->router->pathFor('poll.single',['id'=>"#$poll->id"]));
$this->breadcrumbs[$poll->id] = $url;
return $this->view->render($response, 'polls/single.tpl',[
'poll' => $poll,
'breadcrumbs' => $this->breadcrumbs,
'ogdata' => $this->ogdata
]);
}


public function getPoll($id){
$id = filter_var($id, FILTER_VALIDATE_INT);
$poll = $this->DB->row("SELECT tbl_poll_question.*,
SEC_TO_TIME(TIMESTAMPDIFF(SECOND, tbl_poll_question.starttime, tbl_poll_question.endtime)) AS duration,
IF(tbl_poll_question.endtime < NOW(), 1, 0) AS ended,
count(tbl_poll_vote.id) + count(tbl_poll_textreply.id) as totalVotes
FROM tbl_poll_question
LEFT JOIN tbl_poll_vote ON tbl_poll_question.id = tbl_poll_vote.pollid
LEFT JOIN tbl_poll_textreply ON tbl_poll_question.id = tbl_poll_textreply.pollid
WHERE tbl_poll_question.id = ?
AND (tbl_poll_question.dontshow = 0 OR tbl_poll_question.dontshow = 1 AND tbl_poll_question.endtime < NOW())
AND tbl_poll_question.adminonly = 0
GROUP BY tbl_poll_question.id
ORDER BY tbl_poll_question.id DESC", $id);

if('TEXT' == $poll->polltype){
$poll->results = $this->DB->run("SELECT * FROM tbl_poll_textreply WHERE pollid = ?", $poll->id);
} else {
if (!$filter){
$poll->results = $this->DB->run("SELECT COUNT(tbl_poll_vote.id) AS votes,
tbl_poll_option.text AS `option`
FROM tbl_poll_vote
LEFT JOIN tbl_poll_option ON tbl_poll_vote.optionid = tbl_poll_option.id
WHERE tbl_poll_vote.pollid = ?
GROUP BY tbl_poll_vote.optionid
ORDER BY votes DESC", $poll->id);
} else {
$poll->results = $this->DB->run("SELECT
COUNT(o.id) AS votes,
o.text AS `option`
FROM ss13poll_vote AS v
LEFT JOIN ss13poll_option AS o ON (v.optionid = o.id)
LEFT JOIN ss13player AS p ON (v.ckey = p.ckey)
LEFT JOIN ss13poll_question AS q ON (v.pollid = q.id)
WHERE v.pollid = ?
AND
(SELECT SUM(j.delta)
FROM ss13role_time_log AS j
WHERE j.job IN ('Living')
AND j.datetime BETWEEN q.starttime - INTERVAL 30 DAY AND q.starttime
AND j.ckey = v.ckey) >= 60
GROUP BY o.text
ORDER BY votes DESC;", $poll->id);
}
}

$poll = $this->pollModel->parsePoll($poll);
return $poll;
}



}
45 changes: 45 additions & 0 deletions src/Statbus/Models/Poll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Statbus\Models;

class Poll {

private $settings;

public function __construct(){

}

public function parsePoll(&$poll){
switch($poll->polltype){
case 'OPTION':
$poll->type = "Option";
break;
case 'TEXT':
$poll->type = "Text Reply";
break;
case 'NUMVAL':
$poll->type = "Numerical Rating";
break;
case 'MULTICHOICE':
$poll->type = "Multiple Choice";
break;
case 'IRV':
$poll->type = "Instant Runoff Voting";
break;
}
if(isset($poll->results)){
foreach($poll->results as &$r){
$r->percent = floor(($r->votes / $poll->totalVotes) * 100);
}
}
return $poll;
}


public function mapPollType($type){

}

}

11 changes: 11 additions & 0 deletions src/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,17 @@
$this->post('/library/{id:[0-9]+}/delete', \Statbus\Controllers\LibraryController::class . ':deleteBook')->setName('library.delete');
});

//Polls
$app->group('', function () {

//Index
$this->get('/polls[/page/{page}]', \Statbus\Controllers\PollController::class . ':index')->setName('poll.index');

//Single Poll
$this->get('/polls/{id:[0-9]+}', \Statbus\Controllers\PollController::class . ':single')->setName('poll.single');

});

//TGDB
$app->group('', function () {

Expand Down
3 changes: 3 additions & 0 deletions templates/base/nav.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
Library
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{path_for('poll.index')}}"><i class="fas fa-vote-yea"></i> Polls</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="" role="button" aria-haspopup="true" aria-expanded="farlse"><i class="fas fa-info-circle"></i> Info</a>
<div class="dropdown-menu">
Expand Down
39 changes: 39 additions & 0 deletions templates/polls/listing.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% extends "base/index.html"%}
{% block pagetitle %}Polls{% endblock %}
{% block content %}
<div class="row">
<div class="col">
{% set vars = {
'nbPages': poll.pages,
'currentPage': poll.page,
'url': path_for('poll.index')
}
%}
{% include 'components/pagination.html' with vars %}
</div>
</div>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Question</th>
<th>Duration</th>
<th>Responses</th>
</tr>
</thead>
<tbody>
{% for poll in polls %}
<tr>
<td><a href="{{path_for('poll.single',{'id': poll.id})}}">{{poll.id}}</a></td>
<td>{{poll.type}}</td>
<td>{{poll.question|raw}}</td>
<td>{{poll.duration}}</td>
<td>{{poll.totalVotes}}</td>
</tr>
{% endfor %}
</tbody>
</table>

{% include 'components/pagination.html' with vars %}
{% endblock %}
48 changes: 48 additions & 0 deletions templates/polls/single.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{% extends "index.tpl"%}
{% block content%}
<h4><small class="text-muted">#{{poll.id}} {{poll.createdby_ckey}} asks:</small><br>
{{poll.question|nl2br}}</h4>
<hr>

<div class="row mb-4">
<div class="col text-right lead">
<strong>Started</strong><br>
{{poll.starttime|timestamp|raw}}
</div>
<div class="col text-center lead">
<strong>Duration</strong><br>
{{poll.duration}}
</div>
<div class="col lead text-center">
<strong>Responses</strong><br>
{{poll.totalVotes}}
{% if poll.filtered %}
<br><small>Does NOT reflect filtered votes!</small>
{% endif %}
</div>
<div class="col lead">
<strong>Ended</strong><br>
{{poll.endtime|timestamp|raw}}
</div>
</div>
{% if poll.ended %}
<div class="alert alert-info">This poll has ended</div>
{% endif %}

{% if poll.filtered %}
<div class="alert alert-danger"><strong>VIEWING FILTERED RESULTS</strong></div>
{% endif %}
<hr>

{% if poll.polltype == 'TEXT' %}
{% include 'polls/types/text.tpl' %}
{% elseif poll.polltype == 'MULTICHOICE' %}
{% include 'polls/types/option.tpl' %}
{% elseif poll.polltype == 'OPTION' %}
{% include 'polls/types/option.tpl' %}
{% elseif poll.polltype == 'IRV' %}
{% include 'polls/types/irv.tpl' %}
{% endif %}


{% endblock %}
1 change: 1 addition & 0 deletions templates/polls/types/irv.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p class="lead">Instant Runoff Polls results are not currently parsed by Statbus. We apologize for the inconvenience.</p>
27 changes: 27 additions & 0 deletions templates/polls/types/multichoice.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{% for r in poll.results %}
{% if r.replytext == 'ABSTAIN' %}
<p class="text-center text-muted">&laquo; Abstained &raquo;</p>
{% else %}
<dl class="row" id="{{r.id}}">
<dt class="col-md-2">
{{r.datetime}}<br>
<a href="#{{r.id}}">#{{r.id}}</a>
{% if user.ckey and user.level >= 2 %}
| <a href="{{app.url}}tgdb/player.php?ckey={{r.ckey}}">
{{r.ckey}}
</a>
{% endif %}
</dt>
<dd class="col-md-10">
<blockquote class="blockquote">
{{r.replytext|nl2br}}
</blockquote>
</dd>
</dl>
{% endif %}
{% if loop.last %}
{% else %}
<hr>
{% endif %}

{% endfor %}
25 changes: 25 additions & 0 deletions templates/polls/types/option.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<table class="table table-sm table-bordered sort">
<thead>
<tr>
<th>Votes</th>
<th>Percentage</th>
<th>Option</th>
</tr>
</thead>
<tbody>
{% for r in poll.results %}
<tr>
<th>
{{r.votes}}
</th>
<td>
{{r.percent}}
</td>
<td>
{{r.option|nl2br}}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<p class="text-muted"><em>Percentages are rounded down to the nearest whole number for the sake of readability</em></p>
22 changes: 22 additions & 0 deletions templates/polls/types/text.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% for r in poll.results %}
{% if r.replytext == 'ABSTAIN' %}
<p class="text-center text-muted">&laquo; Abstained &raquo;</p>
{% else %}
<dl class="row" id="{{r.id}}">
<dt class="col-md-2">
{{r.datetime}}<br>
<a href="#{{r.id}}">#{{r.id}}</a>
</dt>
<dd class="col-md-10">
<blockquote class="blockquote">
{{r.replytext|nl2br}}
</blockquote>
</dd>
</dl>
{% endif %}
{% if loop.last %}
{% else %}
<hr>
{% endif %}

{% endfor %}

0 comments on commit 3dbd481

Please sign in to comment.