Browse Source

first php commit

master
myitinos 2 years ago
parent
commit
a15b3be600
15 changed files with 1873 additions and 1 deletions
  1. +7
    -0
      CONTRIBUTING.md
  2. +5
    -0
      Dockerfile
  3. +60
    -1
      README.md
  4. +43
    -0
      authenticate.php
  5. +34
    -0
      components/card-vote.php
  6. +26
    -0
      components/card.php
  7. +12
    -0
      conn/db.php
  8. +504
    -0
      count.php
  9. +302
    -0
      index.php
  10. +3
    -0
      info.php
  11. +27
    -0
      login.php
  12. +652
    -0
      private.php
  13. +13
    -0
      signout.php
  14. +40
    -0
      tampilanSION.php
  15. +145
    -0
      validate.php

+ 7
- 0
CONTRIBUTING.md View File

@ -0,0 +1,7 @@
### Hal Yang Harus Diperhatikan
- Gunakan sintaks PHP dengan versi <= 5.3
- Ngoding yang rapi. Udah dirapiin sebelumnya biar tidak berantakan lagi. Script nya udah eneg untuk dilihat, jangan dibuat lebih eneg lagi :'.
- Kalau ada nyisipin `echo` di bagian HTML, pakai `<?= $var >`. Supaya lebih mudah untuk dilihat
- Jika ingin membuat fungsi helper, silahkan buat di file `utils/helper.php` dengan mengikuti format yang dijelaskan di file tersebut.
- Kalau mau main-main script, bisa dilakukan di folder `playground`.

+ 5
- 0
Dockerfile View File

@ -0,0 +1,5 @@
FROM php
COPY . /app
WORKDIR /app
CMD php -S 127.0.0.1:8080
EXPOSE 8080:8080

+ 60
- 1
README.md View File

@ -1,2 +1,61 @@
# pemira
# 1. Tentang
Sistem ini terdiri dari 4 bagian utama, yakni:
- Halaman voting (`index.php`)
- Halaman hasil voting (`private.php`).
- Halaman hasil voting, bisa diakses setelah pengumuman (`count.php`).
- Form input calon (`/input/index.php`).
# 2. Komponen
## 2.1. Halaman Voting
Halaman ini hanya bisa diakses oleh selain panitia, dikarenakan panitia harus netral selama Pemira. Halaman ini hanya bisa diakses ketika mahasiswa belum melakukan voting sebelumnya. Mahasiswa yang sudah voting sebelumnya akan diarahkan langsung ke halaman SION.
## 2.2. Halaman Hasil Voting (Private)
Halaman ini dikhususkan untuk tim IT Support, Ketua, dan Wakil panitia . Di halaman ini, user bisa melihat hasil perhitungan suara yang masuk, grafik, serta jumlah suara yang valid dan tidak valid.
## 2.3. Halaman Hasil Voting (Pengumuman)
Halaman ini dikhususkan untuk tim IT Support, Ketua, dan Wakil panitia. Halaman ini hanya bisa diakses setelah pengumuman. Di halaman ini, user bisa melihat hasil perhitungan suara yang masuk dan grafik.
## 2.4. Form Input Calon
Berfungsi untuk menginputkan data calon. Hanya dipakai di lokal saja, fitur ini tidak akan di-upload ke live server.
# 3. Flowchart
![Flowchart](https://trello-attachments.s3.amazonaws.com/5bae00dbbadef173ef6bf815/5bb35bfeea9e9c09f9f12fe1/a4976cddb9154060c5b7effcec6016be/IMG_20181013_130725_170.jpg)
# 4. Production
Ketika akan mengupload sistem ini ke live server, ada beberapa file/folder yang tidak boleh di upload ke live server. File/folder berikut adalah:
- `/db`
- `/input`
- `/playground`
# 5. Pengembangan
## 5.1. Setup DB
1. Import DB menggunakan file dari folder `db`, gunakan file dengan suffix tanggal terbaru. Hapus bagian `ON PRIMARY...` dan `LOG ON..` di `CREATE DATABASE ...` kalau menemukan masalah ketika meng-import data.
2. Buat file `db.php` di dalam folder `/conn`, tinggal copy-paste dari file `db.php.example`.
3. Atur variabel `$server`, `$database`, `$user`, dan `$password` sesuai dengan konfigurasi PC anda. Referensi:
- http://php.net/manual/en/function.odbc-connect.php.
- Cari nama server: https://stackoverflow.com/a/18765207.
- $user dan $password pakai yg di bagian login ke SQL Server.
# 6. Penggunaan
## 6.1. Mahasiswa Biasa
1. Login dari `login.php`
2. Redirect ke halaman SION (dummy).
3. Redirect ke `index.php` jika belum voting.
4. Jika sudah selesai vote, maka akan otomatis logout.
5. Ketika login kembali, maka user tersebut akan diarahkan ke halaman SION (dummy), kalau di live server akan diarahkan langsung ke homepage SION.
6. **Logout manual** bisa dilakukan dengan beralih ke `/signout.php`.
## 6.2. Panitia
1. Login dari `login.php`
2. Redirect ke halaman SION (dummy).
3. Panitia selain IT Support, ketua, & wakil panitia tidak bisa mengakses `private.php` dan `count.php`.
## 6.3. IT Support, Ketua & Wakil Panitia
1. Login dari `login.php`
2. Redirect ke halaman SION (dummy).
3. Untuk mengakses `private.php`, dilakukan dengan cara beralih ke `/<folder pemira>/private.php`.

+ 43
- 0
authenticate.php View File

@ -0,0 +1,43 @@
<?php
/**
* Mempersiapkan session. session.use_trans_sid digunakan untuk menghindari
* penyantuman Session ID pada setiap URL.
*
* Ref: https://stackoverflow.com/questions/1745984/php-session-use-trans-sid
*/
ini_set('session.use_only_cookies', TRUE );
ini_set('session.use_trans_sid', FALSE );
session_start();
require_once("conn/db.php");
require_once('utils/helper.php');
/**
* Cek session serta token. Kemudian menyimpan nilai NIM dari session.
*/
if (!isset($_SESSION['nim']) && !isset($_SESSION['token'])) {
header('location:login.php');
} else {
$nim = $_SESSION['nim'];
}
if ($_POST['formSubmit'] == "Login") {
$nims = $_POST['nim'];
$pass = $_POST['pass'];
$cekuser = odbc_exec($koneksi, "SELECT * FROM tb_mhs WHERE nim = '" . $nims . "'");
$hasil = odbc_fetch_array($cekuser);
if ($pass <> $hasil['pass']) {
echo $pass . ' ' . $hasil['pass'];
echo "Password salah!";
header('location:login.php?s=2');
} else if ($nims <> $hasil['nim']) {
header('location:login.php?s=1');
} else {
$_SESSION['nim'] = $hasil['nim'];
header('location:tampilanSION.php');
}
}

+ 34
- 0
components/card-vote.php View File

@ -0,0 +1,34 @@
<div class="boxes">
<div class="candidate-number">
<center>
<span class="urut"><?= $no; $no++ ?></span>
</center>
</div>
<div class="radio">
<div class="candidate">
<label class="btn btn-default btn-free">
<div class="candidate-photo">
<img class="img-responsive img-thumbnail" src="<?= $item["photo"]; ?>" alt="<?= $item["nama_calon"]; ?>">
</div>
<div class="candidate-name">
<input type="radio" name="<?= $inputName ?>" class="opts" value="<?= $item['id_calon'] . '-' . $item['id_status'] ?>">
<strong><?= $item["nama_calon"]; ?></strong>
</div>
</label>
</div>
</div>
<div class="candidate-visimisi">
<button
type="button"
data-kandidat="<?= $item['nama_calon']; ?>"
data-visi="<?= $item['visi']; ?>"
data-misi="<?= $item['misi']; ?>"
data-img="<?= $item['photo']; ?>"
class="btn btn-info btn-block btn-frees"
data-toggle="modal"
data-target="#visimisi"
data-backdrop="static">Visi & Misi</button>
</div>
</div>

+ 26
- 0
components/card.php View File

@ -0,0 +1,26 @@
<div class="boxes">
<div class="candidate-number">
<center>
<span class="urut"><?= $no; $no++ ?></span>
</center>
</div>
<div class="radio">
<div class="candidate">
<label class="btn btn-default btn-count btn-free active">
<div class="candidate-photo">
<img class="img-responsive img-thumbnail" src="<?= $item["photo"]; ?>" alt="<?= $item["nama_calon"]; ?>">
</div>
<div class="candidate-name candidate-name-p">
<strong><?= $item["nama_calon"]; ?></strong>
</div>
</label>
</div>
</div>
<div class="candidate-stat">
<span class="percentage">
<?= $percentage ?>%
</span> (<?= $item['votes']['count'] ?> Suara)
</div>
</div>

+ 12
- 0
conn/db.php View File

@ -0,0 +1,12 @@
<?php
$server = "localhost";
$database = "pollingpemilu";
$user = "SA";
$pass = "123EmpatLimaEnam";
$koneksi = odbc_connect("Driver={SQL Server};Server=$server;Database=$database;", $user, $pass);
if (!$koneksi) {
echo "500 Error";
}

+ 504
- 0
count.php View File

@ -0,0 +1,504 @@
<?php
session_start();
require_once("conn/db.php");
require_once('utils/helper.php');
if (!isset($_SESSION['nim'])) {
header('location:login.php');
}
//SET TIMEZONE
date_default_timezone_set('Asia/Makassar');
$date = date("Y-m-d H:i");
//CEK PANITIA ISTIMEWA
$nim = $_SESSION['nim'];
$query = odbc_exec($koneksi, "SELECT TOP 1 * FROM tb_panitia WHERE nim_panitia = '$nim' AND role='1'");
$panitia = dbGet($query);
if ($date <= date("Y-m-d H:i", strtotime("2018-10-15 06:00")) || !isset($panitia[0])) {
header('location:tampilanSION.php');
}
// Ambil profil calon
$queryCandidates = "SELECT
id_calon,
nama_calon,
photo,
id_status
FROM
tb_calon
ORDER BY photo";
$execCandidates = odbc_exec($koneksi, $queryCandidates);
$candidates = dbGet($execCandidates);
$pluckedCandidateId = colPluck($candidates, 'id_calon');
// Ambil semua suara yang didapatkan
$stringifyCandidateId = implode("','", $pluckedCandidateId);
$queryVotes = "SELECT
b.id_calon,
COUNT(a.id_pemilu) AS count
FROM
(SELECT
MIN(a.id_pemilu) AS id_pemilu,
b.id_status,
MIN(a.create_at) as create_at
FROM
tb_pemilu a
JOIN
tb_calon b ON a.id_calon = b.id_calon
WHERE
a.id_status IN ('S9af54pY', 'KTU3vVnd')
GROUP BY
a.id_status,
nim_mhs,
b.id_status) a
JOIN tb_pemilu b
ON b.id_pemilu = a.id_pemilu
WHERE
b.id_calon IN ('$stringifyCandidateId')
GROUP BY
b.id_calon
ORDER BY
b.id_calon";
$execVotes = odbc_exec($koneksi, $queryVotes);
$votes = dbGet($execVotes);
$keyedVotes = colKeyBy($votes, 'id_calon');
// Pasang hasil vote ke setiap calon
foreach ($candidates as &$candidate) {
if (!empty($keyedVotes[$candidate['id_calon']])) {
$candidate['votes'] = $keyedVotes[$candidate['id_calon']];
} else {
$candidate['votes'] = [
'id_calon' => $candidate['id_calon'],
'count' => 0
];
}
}
// Ambil sema
$semaTotalVotes = 0;
$sema = array_filter($candidates, function ($item) {
return $item['id_status'] === 'KTU3vVnd';
});
array_reduce($sema, function ($prev, $cur) use (&$semaTotalVotes) {
$prevVotes = (int) $prev['votes']['count'];
$curVotes = (int) $cur['votes']['count'];
$semaTotalVotes += $prevVotes + $curVotes;
});
// Ambil balma
$balmaTotalVotes = 0;
$balma = array_filter($candidates, function ($item) {
return $item['id_status'] === 'S9af54pY';
});
array_reduce($balma, function ($prev, $cur) use (&$balmaTotalVotes) {
$prevVotes = (int) $prev['votes']['count'];
$curVotes = (int) $cur['votes']['count'];
$balmaTotalVotes += $prevVotes + $curVotes;
});
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#2160ac">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hasil Polling Pemilu Raya <?= date('Y') ?></title>
<link href="public/css/bootstrap.css" rel="stylesheet">
<link href="public/fonts/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="public/css/normalize.css" rel="stylesheet">
<link href="public/css/style.css" rel="stylesheet">
<style>
.btn-count.btn-free:active, .btn-count.btn-free.active {
color: #333 !important;
background-color: #fff !important;
}
.btn-count.btn-free:active .candidate-name, .btn-count.btn-free.active .candidate-name {
color: #333 !important;
}
</style>
</head>
<body>
<header>
<div>
<img class="img-responsive shd one" src="public/images/banner.png">
</div>
<div class="clearfix"></div>
</header>
<main>
<div class="text-center lists-striped" data-toggle="buttons"> <!--data-toggle="buttons"-->
<h1 class="ttl" style="font-size:50px; margin-bottom:10px;">HASIL POLLING PEMILU RAYA <?= date('Y') ?><br></h1>
<br>
<p class="ttl" style="font-size:14px; margin-bottom:50px;">Update Terakhir: <span id="last_update"><?= date("d M Y H:i:s"); ?> WITA<span></p>
<h1 class="ttl">Ketua & Wakil Ketua Senat Mahasiswa</h1>
<div class="lines"></div>
<br>
<div class="container">
<div class="row">
<?php
// Looping sema
$no = 1;
foreach ($sema as $key => $item) {
if ($semaTotalVotes > 0) {
$percentage = number_format(($item['votes']['count'] / $semaTotalVotes) * 100, 2, ",", ".");
} else {
$percentage = 0;
}
?>
<div class="col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top:10px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for senat-->
<div class="clearfix"></div>
<div class="shadow"></div>
<!--for balma-->
<div class="text-center lists" data-toggle="buttons" style="margin-bottom : 40px">
<h1 class="ttl">Ketua Badan Legislatif Mahasiswa</h1>
<div class="lines"></div>
<br>
<div class="container">
<div class="row">
<?php
// Looping balma
$no = 1;
foreach ($balma as $key => $item) {
if ($balmaTotalVotes > 0) {
$percentage = number_format(($item['votes']['count'] / $balmaTotalVotes) * 100, 2, ",", ".");
} else {
$percentage = 0;
}
?>
<div class="col-lg-push-2 col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top: 15px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for balma-->
<div class="container">
<center>
<h1 class="ttl">Grafik Pemilihan Sema & Balma</h1>
<div class="lines-divider"></div>
</center>
<div style="margin-bottom : 40px">
<div class="row">
<div class="sema-chart col-md-6">
<center>
<h3 class="chart-title">
Ketua dan Wakil Sema
</h3>
</center>
<div class="title-divider"></div>
<div class="chart-container" style="max-height : 100px;overflow : hidden;">
<canvas id="sema-legend"></canvas>
</div>
<div class="chart-container">
<canvas id="sema-chart" onbeforeprint="beforePrintHandler()"></canvas>
</div>
</div>
<div class="balma-chart col-md-6">
<center>
<h3 class="chart-title">
Ketua Balma
</h3>
</center>
<div class="title-divider"></div>
<div class="chart-container balma-legend" style="overflow : hidden;">
<canvas id="balma-legend"></canvas>
</div>
<div class="chart-container">
<canvas id="balma-chart"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="text-center">
<a href="http://sion.stikom-bali.ac.id" class="btn btn-lg btn-success submit">Lanjut Ke SION <span class="glyphicon glyphicon-chevron-right" ></span></a>
</div>
</main>
<footer>
<div class="clearfix"></div>
<div class="text-center">
<img class="img-responsive one" src="public/images/banner2.png">
<div class="lists-footer">
<p style="margin:0 5px;">Copyright &copy; <?= date('Y') ?> IT Support Pemira</p>
</div>
</div>
</footer>
<script src="public/js/jquery-3.3.1.min.js"></script>
<script src="public/js/bootstrap.min.js"></script>
<script src="public/js/chart.js"></script>
<script src="public/js/chart-label.js"></script>
<script>
function beforePrintHandler () {
for (var id in Chart.instances) {
Chart.instances[id].resize()
}
}
var $ctxSema = document.getElementById("sema-chart").getContext('2d');
var $semaChart = new Chart($ctxSema,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($sema as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}],
labels: [
<?php
foreach($sema as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
plugins : {
labels : {
render : function (args) {
return ((args.value / <?=$semaTotalVotes?>) * 100).toFixed(2) + " %" ;
},
precision : 0,
fontColor : "#FFF",
fontSize : 15,
fontStyle : 'bold'
}
},
responsive : true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return " " + currentValue + ' Suara';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
}
}
});
var $ctxSemaLegend = document.getElementById("sema-legend").getContext('2d');
var $semaLegend = new Chart($ctxSemaLegend,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($sema as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
}],
labels: [
<?php
foreach($sema as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
cutoutPercentage : 100,
plugins : {
labels : {
fontColor : "#FFF",
}
},
}
});
var $ctxBalmaLegend = document.getElementById("balma-legend").getContext('2d');
var $balmaLegend = new Chart($ctxBalmaLegend,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($balma as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
]
}],
labels: [
<?php
foreach($balma as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
cutoutPercentage : 100,
plugins : {
labels : {
fontColor : "#FFF",
}
},
}
});
var $ctxBalma = document.getElementById("balma-chart").getContext('2d');
var $balmaChart = new Chart($ctxBalma,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($balma as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
]
}],
labels: [
<?php
foreach($balma as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
plugins : {
labels : {
render : function (args) {
return ((args.value / <?=$balmaTotalVotes?>) * 100).toFixed(2) + " %" ;
},
precision : 0,
fontColor : "#FFF",
fontSize : 16,
fontStyle : 'bold',
showActualPercentages: true,
showZero: true,
}
},
legend: {
display: false
},
responsive : true,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return " " + currentValue + ' Suara';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
}
}
});
</script>
</body>
</html>

+ 302
- 0
index.php View File

@ -0,0 +1,302 @@
<?php
ini_set('session.use_only_cookies', TRUE);
ini_set('session.use_trans_sid', FALSE);
session_start();
require_once("conn/db.php");
require_once('utils/helper.php');
if (!isset($_SESSION['nim'])) {
header('location:login.php');
} else {
$nim = $_SESSION['nim'];
}
$queryStudent = "SELECT
TOP 1
a.nim,
b.nim_panitia,
b.role,
COUNT(c.id_pemilu) AS votes
FROM
tb_mhs AS a
LEFT JOIN
tb_panitia b ON b.nim_panitia = a.nim
LEFT JOIN
tb_pemilu c ON c.nim_mhs = a.nim
WHERE
a.nim = '$nim'
GROUP BY
a.nim,
b.nim_panitia,
b.role";
$execStudent = odbc_exec($koneksi, $queryStudent);
$student = dbGet($execStudent)[0];
// Cek dia panitia
if ($student['nim_panitia'] != null) {
if ((int) $student['role'] === 1) {
header('location:private.php');
} else {
header('location:tampilanSION.php');
}
}
// Cek dia udah vote atau belom
if ((int) $student['votes'] > 0) {
header('location:tampilanSION.php');
} else {
if (empty($_SESSION['token'])) {
if (function_exists('mcrypt_create_iv')) {
$_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
} else {
$_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
}
}
$token = $_SESSION['token'];
}
// Ambil profil calon
$queryCandidates = "SELECT
a.id_calon,
a.nama_calon,
a.photo,
a.id_status,
b.visi,
b.misi
FROM
tb_calon AS a
INNER JOIN
tb_visimisi b ON b.id_calon = a.id_calon
ORDER BY a.photo";
$execCandidates = odbc_exec($koneksi, $queryCandidates);
$candidates = dbGet($execCandidates);
$sema = array_filter($candidates, function ($item) {
return $item['id_status'] === 'KTU3vVnd';
});
$balma = array_filter($candidates, function ($item) {
return $item['id_status'] === 'S9af54pY';
});
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Poling Pemilu Raya <?= date('Y') ?></title>
<link href="public/css/bootstrap.css" rel="stylesheet">
<link href="public/css/normalize.css" rel="stylesheet">
<link href="public/css/style.css" rel="stylesheet">
</head>
<body>
<header>
<div>
<img class="img-responsive shd one" src="public/images/banner.png">
</div>
<div class="clearfix"></div>
</header>
<main>
<form action="validate.php" method="post">
<div class="text-center lists-striped" data-toggle="buttons">
<h1 class="ttl" style="font-size:50px; margin-bottom:24px;">POLLING PEMILU RAYA <?= date('Y') ?><br></h1>
<p class="text-warning" style="font-size:16px; margin-bottom:24px;">
<em>
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> Pilih 1 calon Sema dan 1 calon Balma, kemudian klik tombol <b>Simpan</b> yang berada di paling bawah untuk menyimpan vote anda.
</em>
</p>
<!--data-toggle="buttons"-->
<input type="hidden" name="token_" value="<?= $token ?>" />
<?php
if (isset($_SESSION['get'])) {
$get = $_GET['get'];
if ($get == 1) {
$msg = 'Ada Katagori yang belum di polling';
} else if($get == 2) {
$msg = 'Tidak bisa melakukan poling lagi';
} else if($get == 3) {
$msg = 'Tidak dapat melakukan poling';
} else {
$msg = 'Tidak dapat melakukan poling, silahkan coba kembali !';
}
?>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-push-3 col-sm-10 col-sm-push-1">
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<strong>
<span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span> <?= $msg; ?>
</strong>
</div>
</div>
</div>
</div>
<?php
}
unset($_SESSION['get']);
?>
<!-- <div class="stripe"></div> -->
<h1 class="ttl">Calon Ketua & Wakil Ketua Senat Mahasiswa</h1>
<div class="lines"></div>
<p class="text-warning">
<em>
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> Klik salah satu foto atau nama untuk polling
</em>
</p>
<div class="container">
<div class="row">
<?php
$no = 1;
$inputName = 'senat';
foreach ($sema as $key => $item) {
?>
<div class="col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card-vote.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top:10px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for senat-->
<div class="clearfix"></div>
<div class="shadow"></div>
<!--for balma-->
<div class="text-center lists" data-toggle="buttons">
<!-- <div class="stripe"></div> -->
<h1 class="ttl">Calon Ketua Badan Legislatif Mahasiswa</h1>
<div class="lines"></div>
<p class="text-warning">
<em>
<span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span> Klik salah satu foto atau nama untuk polling
</em>
</p>
<div class="container">
<div class="row">
<?php
$no = 1;
$inputName = 'balma';
foreach ($balma as $key => $item) {
?>
<div class="col-lg-push-2 col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card-vote.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top: 15px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for balma-->
<div class="clearfix"></div>
<!--end for modal-->
<div class="text-center">
<button type="submit" name="formSubmit" value="Submit" class="btn btn-lg btn-success submit">Simpan <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span></button>
</div>
</form>
</main>
<footer>
<div class="clearfix"></div>
<div class="text-center">
<img class="img-responsive one" src="public/images/banner2.png">
<div class="lists-footer">
<p style="margin:0 5px;">Copyright &copy; <?= date('Y') ?> IT Support Pemira</p>
</div>
</div>
</footer>
<!--for modal-->
<div class="modal fade" id="visimisi" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-md">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" style="text-align:center;"></h4>
</div>
<div class="modal-body">
<div class="imginsert" style="text-align:center;"></div>
<h2 style="text-align:center;">Visi</h2>
<div class="visi"></div>
<h2 style="text-align:center;">Misi</h2>
<div class="misi"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Tutup</button>
</div>
</div>
</div>
</div>
<script src="public/js/jquery-3.3.1.min.js"></script>
<script src="public/js/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
$('#visimisi').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
var recipient = button.data('kandidat')
var recipient2 = button.data('visi')
var recipient3 = button.data('misi')
var recipient4 = button.data('img')
var modal = $(this)
modal.find('.modal-title').text(recipient)
modal.find('.visi').html(recipient2)
modal.find('.misi').html(recipient3)
modal.find('.imginsert').html('<img class="img-responsive img-thumbnail" src="' + recipient4 + '" alt="asdad">')
});
});
</script>
</body>
</html>

+ 3
- 0
info.php View File

@ -0,0 +1,3 @@
<?php
phpinfo();

+ 27
- 0
login.php View File

@ -0,0 +1,27 @@
<?php
session_start();
if (isset($_SESSION['nim'])) {
header('location:index.php');
}
require_once("conn/db.php");
?>
<html>
<head>
<title>Login Pemira</title>
<link rel="stylesheet" href="public/css/bootstrap.min.css" />
</head>
<body>
<form action="authenticate.php" method="POST">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">@</span>
<input type="text" name="nim" class="form-control" placeholder="Username" aria-describedby="basic-addon1">
<input type="password" name="pass" class="form-control" placeholder="Password" aria-describedby="basic-addon1">
<input type="submit" name="formSubmit" value="Login" />
</div>
</form>
</body>
</html>

+ 652
- 0
private.php View File

@ -0,0 +1,652 @@
<?php
session_start();
require_once("conn/db.php");
require_once('utils/helper.php');
if (!isset($_SESSION['nim'])) {
header('location:login.php');
}
date_default_timezone_set('Asia/Makassar');
$date = date("Y-m-d H:i");
if ($date <= date("Y-m-d H:i", strtotime("2016-12-05 23:59"))) {
header('location:tampilanSION.php');
}
//CEK PANITIA / TIDAK :
$nim = $_SESSION['nim'];
$query = odbc_exec($koneksi, "SELECT TOP 1 * FROM tb_panitia WHERE nim_panitia = '$nim' AND role='1'");
$panitia = dbGet($query);
if (!isset($panitia[0])) {
header('location:tampilanSION.php');
}
// Ambil profil calon
$queryCandidates = "SELECT
id_calon,
nama_calon,
photo,
id_status
FROM
tb_calon
ORDER BY photo";
$execCandidates = odbc_exec($koneksi, $queryCandidates);
$candidates = dbGet($execCandidates);
$pluckedCandidateId = colPluck($candidates, 'id_calon');
// Ambil semua suara yang didapatkan
$stringifyCandidateId = implode("','", $pluckedCandidateId);
$queryVotes = "SELECT
b.id_calon,
COUNT(a.id_pemilu) AS count
FROM
(SELECT
MIN(a.id_pemilu) AS id_pemilu,
b.id_status,
MIN(a.create_at) as create_at
FROM
tb_pemilu a
JOIN
tb_calon b ON a.id_calon = b.id_calon
WHERE
a.id_status IN ('S9af54pY', 'KTU3vVnd')
GROUP BY
a.id_status,
nim_mhs,
b.id_status) a
JOIN tb_pemilu b
ON b.id_pemilu = a.id_pemilu
WHERE
b.id_calon IN ('$stringifyCandidateId')
GROUP BY
b.id_calon
ORDER BY
b.id_calon";
$execVotes = odbc_exec($koneksi, $queryVotes);
$votes = dbGet($execVotes);
$keyedVotes = colKeyBy($votes, 'id_calon');
$queryAllVotes = "SELECT
id_calon,
COUNT(id_pemilu) AS allCount
FROM
tb_pemilu
WHERE
id_calon IN ('$stringifyCandidateId')
GROUP BY
id_calon
ORDER BY
id_calon";
$execAllVotes = odbc_exec($koneksi, $queryAllVotes);
$allVote = dbGet($execAllVotes);
$keyedAllVotes = colKeyBy($allVote, 'id_calon');
// Pasang hasil vote ke setiap calon
foreach ($candidates as &$candidate) {
if (!empty($keyedVotes[$candidate['id_calon']])) {
$candidate['votes'] = $keyedVotes[$candidate['id_calon']];
} else {
$candidate['votes'] = [
'id_calon' => $candidate['id_calon'],
'count' => 0
];
}
if (!empty($keyedAllVotes[$candidate['id_calon']]['allCount'])) {
$candidate['votes']['allCount'] = $keyedAllVotes[$candidate['id_calon']]['allCount'];
} else {
$candidate['votes']['allCount'] = 0;
}
}
// Ambil sema
$semaTotalVotes = 0;
$sema = array_filter($candidates, function ($item) {
return $item['id_status'] === 'KTU3vVnd';
});
array_reduce($sema, function ($prev, $cur) use (&$semaTotalVotes) {
$prevVotes = (int) $prev['votes']['count'];
$curVotes = (int) $cur['votes']['count'];
$semaTotalVotes += $prevVotes + $curVotes;
});
// Ambil balma
$balmaTotalVotes = 0;
$balma = array_filter($candidates, function ($item) {
return $item['id_status'] === 'S9af54pY';
});
array_reduce($balma, function ($prev, $cur) use (&$balmaTotalVotes) {
$prevVotes = (int) $prev['votes']['count'];
$curVotes = (int) $cur['votes']['count'];
$balmaTotalVotes += $prevVotes + $curVotes;
});
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#2160ac">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hasil Sementara Polling Pemilu Raya <?= date('Y') ?></title>
<link href="public/css/bootstrap.css" rel="stylesheet">
<link href="public/fonts/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="public/css/normalize.css" rel="stylesheet">
<link href="public/css/style.css" rel="stylesheet">
<style>
.btn-count.btn-free:active, .btn-count.btn-free.active {
color: #333 !important;
background-color: #fff !important;
}
.btn-count.btn-free:active .candidate-name, .btn-count.btn-free.active .candidate-name {
color: #333 !important;
}
</style>
</head>
<body>
<header>
<div>
<img class="img-responsive shd one" src="public/images/banner.png">
</div>
<div class="clearfix"></div>
</header>
<main>
<div class="text-center lists-striped" data-toggle="buttons"> <!--data-toggle="buttons"-->
<h1 class="ttl" style="font-size:50px; margin-bottom:10px;">HASIL SEMENTARA POLLING PEMILU RAYA <?= date('Y') ?><br></h1>
<br>
<p class="ttl" style="font-size:14px; margin-bottom:50px;">Update Terakhir: <span id="last_update"><?= date("d M Y H:i:s"); ?> WITA<span></p>
<h1 class="ttl">Ketua & Wakil Ketua Senat Mahasiswa</h1>
<div class="lines"></div>
<br>
<div class="container">
<div class="row">
<?php
// Looping sema
$no = 1;
foreach ($sema as $key => $item) {
if ($semaTotalVotes > 0) {
$percentage = number_format(($item['votes']['count'] / $semaTotalVotes) * 100, 2, ",", ".");
} else {
$percentage = 0;
}
?>
<div class="col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top:10px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for senat-->
<div class="clearfix"></div>
<div class="shadow"></div>
<!--for balma-->
<div class="text-center lists" data-toggle="buttons" style="margin-bottom : 40px">
<h1 class="ttl">Ketua Badan Legislatif Mahasiswa</h1>
<div class="lines"></div>
<br>
<div class="container">
<div class="row">
<?php
// Looping sema
$no = 1;
foreach ($balma as $key => $item) {
if ($balmaTotalVotes > 0) {
$percentage = number_format(($item['votes']['count'] / $balmaTotalVotes) * 100, 2, ",", ".");
} else {
$percentage = 0;
}
?>
<div class="col-lg-push-2 col-lg-4 col-md-6 col-sm-6 col-xs-12">
<?php include('./components/card.php'); ?>
</div>
<?php
}
?>
</div>
</div>
<div class="clearfix" style="margin-top: 15px;"></div>
<!-- <div class="stripe-reverse"></div> -->
</div>
<!--end for balma-->
<div class="container">
<center>
<h1 class="ttl">Grafik Pemilihan Sema & Balma</h1>
<div class="lines-divider"></div>
</center>
<div style="margin-bottom : 40px">
<div class="row">
<div class="sema-chart col-md-6">
<center>
<h3 class="chart-title">
Ketua dan Wakil Sema
</h3>
</center>
<div class="title-divider"></div>
<div class="chart-container" style="max-height : 100px;overflow : hidden;">
<canvas id="sema-legend"></canvas>
</div>
<div class="chart-container">
<canvas id="sema-chart" onbeforeprint="beforePrintHandler()"></canvas>
</div>
</div>
<div class="balma-chart col-md-6">
<center>
<h3 class="chart-title">
Ketua Balma
</h3>
</center>
<div class="title-divider"></div>
<div class="chart-container balma-legend" style="overflow : hidden;">
<canvas id="balma-legend"></canvas>
</div>
<div class="chart-container">
<canvas id="balma-chart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!--tabel jumlah suara-->
<div style="margin-bottom : 40px">
<div class="container">
<center style="margin-bottom : 32px">
<h1 class="ttl">Tabel Jumlah Suara</h1>
<div class="lines-divider"></div>
</center>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Calon</th>
<th>Tipe</th>
<th>Persentase</th>
<th>Suara Sah</th>
<th>Suara Tidak Sah</th>
<th>Total Suara</th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
$legal_vote = 0;
$ilegal_vote = 0;
$count = 0;
foreach ($candidates as &$candidate) {
$status = $candidate["id_status"];
if ($status == "KTU3vVnd") {
$type = "SEMA";
} elseif ($status == "S9af54pY") {
$type = "BALMA";
} else {
$type = "Unknown";
}
?>
<tr>
<td>
<?= $candidate["nama_calon"] ?>
</td>
<td>
<?= $type ?>
</td>
<td align="right">
<?php
if ($type === "SEMA") {
$number_of_votes = $semaTotalVotes;
$count_candidates = count($sema);
} else if ($type === "BALMA") {
$number_of_votes = $balmaTotalVotes;
$count_candidates = count($balma);;
}
if ($number_of_votes > 0) {
$percentage = number_format(($candidate["votes"]["count"] / $number_of_votes) * 100, 2, ",", ".");
} else {
$percentage = 0;
}
?>
<?= $percentage ?>%
</td>
<td align="right">
<?php
echo $candidate["votes"]["count"];
$legal_vote += $candidate["votes"]["count"];
?>
</td>
<td align="right">
<?php
$data = $candidate['votes']['allCount'] - $candidate["votes"]["count"];
echo $data;
$ilegal_vote += $data;
?>
</td>
<td align="right">
<?php
echo $candidate['votes']['allCount'];
$count += $candidate['votes']['allCount'];
?>
</td>
</tr>
<?php
$i++;
if ($i == $count_candidates) {
?>
<tr>
<th class="text-right" colspan="3">Total</th>
<th class="text-right"><?= $legal_vote ?></th>
<th class="text-right"><?= $ilegal_vote ?></th>
<th class="text-right"><?= $count ?></th>
</tr>
<?php
$i = 0;
$legal_vote = 0;
$ilegal_vote = 0;
$count = 0;
}
?>
<?php
}
?>
</tbody>
</table>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="text-center">
<a href="http://sion.stikom-bali.ac.id" class="btn btn-lg btn-success submit">LANJUT KE SION <span class="glyphicon glyphicon-chevron-right" ></span></a>
</div>
</main>
<footer>
<div class="clearfix"></div>
<div class="text-center">
<img class="img-responsive one" src="public/images/banner2.png">
<div class="lists-footer">
<p style="margin:0 5px;">Copyright &copy; <?= date('Y') ?> IT Support Pemira</p>
</div>
</div>
</footer>
<script src="public/js/jquery-3.3.1.min.js"></script>
<script src="public/js/bootstrap.min.js"></script>
<script src="public/js/chart.js"></script>
<script src="public/js/chart-label.js"></script>
<script>
function beforePrintHandler () {
for (var id in Chart.instances) {
Chart.instances[id].resize()
}
}
var $ctxSema = document.getElementById("sema-chart").getContext('2d');
var $semaChart = new Chart($ctxSema,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($sema as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}],
labels: [
<?php
foreach($sema as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
plugins : {
labels : {
render : function (args) {
return ((args.value / <?=$semaTotalVotes?>) * 100).toFixed(2) + " %" ;
},
precision : 0,
fontColor : "#FFF",
fontSize : 15,
fontStyle : 'bold'
}
},
responsive : true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return " " + currentValue + ' Suara';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
}
}
});
var $ctxSemaLegend = document.getElementById("sema-legend").getContext('2d');
var $semaLegend = new Chart($ctxSemaLegend,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($sema as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
}],
labels: [
<?php
foreach($sema as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
cutoutPercentage : 100,
plugins : {
labels : {
fontColor : "#FFF",
}
},
}
});
var $ctxBalmaLegend = document.getElementById("balma-legend").getContext('2d');
var $balmaLegend = new Chart($ctxBalmaLegend,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($balma as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
]
}],
labels: [
<?php
foreach($balma as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
cutoutPercentage : 100,
plugins : {
labels : {
fontColor : "#FFF",
}
},
}
});
var $ctxBalma = document.getElementById("balma-chart").getContext('2d');
var $balmaChart = new Chart($ctxBalma,{
type: 'pie',
data: {
datasets: [{
data: [
<?php
foreach($balma as $key => $value) {
echo $value['votes']['count'].",";
}
?>
],
backgroundColor: [
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
]
}],
labels: [
<?php
foreach($balma as $key => $value) {
echo "'".$value['nama_calon']."',";
}
?>
],
},
options: {
plugins : {
labels : {
render : function (args) {
return ((args.value / <?=$balmaTotalVotes?>) * 100).toFixed(2) + " %" ;
},
precision : 0,
fontColor : "#FFF",
fontSize : 16,
fontStyle : 'bold',
showActualPercentages: true,
showZero: true,
}
},
legend: {
display: false
},
responsive : true,
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
let dataset = data.datasets[tooltipItem.datasetIndex];
let currentValue = dataset.data[tooltipItem.index];
return " " + currentValue + ' Suara';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
}
}
});
</script>
</body>