defivelib/index.php

398 lines
37 KiB
PHP
Raw Normal View History

2014-01-23 23:48:59 +01:00
<?php
2014-01-24 18:07:59 +01:00
session_start();
date_default_timezone_set("Europe/Paris");
2014-01-24 18:07:59 +01:00
function search($array) {
global $_POST;
return in_array($_POST['start_search'], $array) && in_array($_POST['end_search'], $array);
}
2014-01-24 18:55:06 +01:00
// Generates a token against CSRF
// ==============================
function generate_token($name = '') {
if(session_id() == '')
session_start();
$token = uniqid(rand(), true);
$_SESSION[$name.'_token'] = $token;
$_SESSION[$name.'_token_time'] = time();
return $token;
}
// Checks that the anti-CSRF token is correct
// ==========================================
function check_token($time, $name = '') {
if(session_id() == '')
session_start();
if(isset($_SESSION[$name.'_token']) && isset($_SESSION[$name.'_token_time']) && (isset($_POST['token']) || isset($_GET['token']))) {
if(!empty($_POST['token']))
$token = $_POST['token'];
else
$token = $_GET['token'];
if($_SESSION[$name.'_token'] == $token) {
if($_SESSION[$name.'_token_time'] >= (time() - (int) $time))
return true;
}
}
return false;
}
2014-01-23 23:48:59 +01:00
if(is_file('data/data')) {
$data = unserialize(gzinflate(base64_decode(file_get_contents('data/data'))));
}
else {
$data = array();
}
2014-01-24 18:55:06 +01:00
if(!empty($_GET['suppr']) && !empty($_SESSION['admin']) && !empty($_GET['token'])) {
if(check_token(600, 'defivelib')) {
unlink($data[$_GET['suppr']]);
}
else {
exit("Mauvais token, veuillez réessayer.");
}
2014-01-24 18:07:59 +01:00
}
if(!empty($_GET['deco'])) {
session_destroy();
}
if(is_file('data/config')) {
$config = unserialize(gzinflate(base64_decode(file_get_contents('data/config'))));
if(!empty($_GET['code']) && $_GET['code'] == $config[0]) {
$_SESSION['admin'] = true;
}
}
$search = false;
2014-01-24 18:55:06 +01:00
if(!empty($_POST['start_search']) && !empty($_POST['end_search']) & !empty($_POST['token'])) {
if(check_token(600, 'defivelib')) {
$search = true;
$data = array_filter($data, "search");
}
else {
exit("Mauvais token, veuillez réessayer.");
}
}
2014-01-23 23:48:59 +01:00
if((!empty($_POST['time_min']) || !empty($_POST['time_sec'])) && !empty($_POST['start']) && !empty($_POST['end'])) {
2014-01-24 18:55:06 +01:00
if(check_token(600, 'defivelib')) {
$min = (!empty($_POST['time_min'])) ? (int) $_POST['time_min'] : 0;
$sec = (!empty($_POST['time_sec'])) ? (int) $_POST['time_sec'] : 0;
$pseudo = (!empty($_POST['pseudo'])) ? $_POST['pseudo'] : "Anonyme";
2014-01-23 23:48:59 +01:00
2014-01-24 18:55:06 +01:00
$data[] = array("date"=>time(), "start"=>(int) $_POST['start'], "end"=>(int) $_POST['end'], "min"=>$min, "sec"=>$sec, "pseudo"=>$pseudo);
2014-01-23 23:48:59 +01:00
2014-01-24 18:55:06 +01:00
// TODO : Upload + taille max de l'upload
2014-01-23 23:48:59 +01:00
2014-01-24 18:55:06 +01:00
if(count($data) == 1 || $min != $data[count($data)-2]['min'] || $sec != $data[count($data)-2]['sec'] || $_POST['start'] != $data[count($data)-2]['start'] || $_POST['end'] != $data[count($data)-2]['end'] || $pseudo != $data[count($data)-2]['pseudo']) {
file_put_contents('data/data', base64_encode(gzdeflate(serialize($data))));
}
}
else {
exit("Mauvais token, veuillez réessayer.");
2014-01-23 23:48:59 +01:00
}
}
2014-01-24 18:55:06 +01:00
$token = generate_token('defivelib');
2014-01-23 23:48:59 +01:00
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
2014-01-24 18:07:59 +01:00
<title>DéfiVélib</title>
2014-01-23 23:48:59 +01:00
<meta name="author" content="phyks">
<style type="text/css" media="screen">
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: sans-serif;
background-color: lightgrey;
background-image: url(data:image/png;base64,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
}
#main {
width: 50%;
min-height: 50%;
margin: auto;
background-color: white;
text-align: center;
padding: 1em;
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
2014-01-24 19:07:02 +01:00
@media (max-width: 1050px) {
#main {
width: 100% !important;
}
}
#main h1 {
margin: 0;
border: 1px solid black;
background-color: rgb(117, 170, 39);
}
#main h2 {
text-align: left;
}
#main h1 a {
color: black;
text-decoration: none;
font-size: 1.5em;
}
table td, th {
padding: 0.5em;
border: 1px solid black;
}
table th {
background-color: rgba(117, 170, 39, 0.4);
}
table {
border-collapse: collapse;
margin: auto;
}
fieldset {
background-color: rgba(17, 78, 121, 0.1);
}
2014-01-24 18:55:06 +01:00
#disclaimer {
font-size: 0.75em;
}
#disclaimer p {
text-align: left;
}
</style>
2014-01-23 23:48:59 +01:00
</head>
<body>
<div id="main">
<h1><a href="index.php">DéfiVélib</a></h1>
<?php
if(!is_dir('data/')) {
mkdir('data/');
}
if(!is_file('data/config')) //First run
{
//Define a new synchronisation code
$code_synchro = substr(sha1(rand(0,30).time().rand(0,30)),0,10);
file_put_contents('data/config', base64_encode(gzdeflate(serialize(array($code_synchro))))); //Save it in data/data file
$_GET['code'] = $code_synchro;
echo "<p>
Définition du code de synchronisation.<br/>
Vous pouvez désormais mettre à jour la liste des stations en visitant l'adresse suivante (update URL) :<br/>
<a href='http://" . $_SERVER["SERVER_NAME"].$_SERVER['REQUEST_URI']."?update=1&code=".$code_synchro."'>http://" . $_SERVER["SERVER_NAME"].$_SERVER['REQUEST_URI']."?update=1&code=".$code_synchro."</a>
</p>
<p>
Il est possible d'automatiser la tâche via une tâche cron. Par exemple (see README) :<br/>
* * * * * wget -q -O <a href='http://" . $_SERVER["SERVER_NAME"].$_SERVER['REQUEST_URI']."?update=1&code=".$code_synchro."'>http://" . $_SERVER["SERVER_NAME"].$_SERVER['REQUEST_URI']."?update=1&code=".$code_synchro."</a> #Commande de mise a jour des stations de velib
</p>";
}
if(!empty($_GET['update']) || !empty($code_synchro)) //If we want to make an update (or first run)
{
if(empty($code_synchro) && is_file('data/config')) //If not first run, get the synchronisation code from data file
{
$data = unserialize(gzinflate(base64_decode(file_get_contents('data/config'))));
$code_synchro = $data[0];
}
if(!empty($_GET['code']) && $_GET['code'] == $code_synchro) //Once we have the code and it is correct
{
$stations_xml = simplexml_load_file('http://www.velib.paris.fr/service/carto');
$liste_stations = array();
foreach($stations_xml->markers->marker as $station) {
$liste_stations[(int) $station['number']] = array('name'=>(string) $station['name'], 'address'=>(string) $station['fullAddress'], 'lat'=>(float) $station['lat'], 'lng'=>(float) $station['lng']);
}
file_put_contents('data/stations', base64_encode(gzdeflate(serialize($liste_stations))));
echo "<p>Mise à jour de la liste des stations effectuée avec succès (Update successful).</p>";
}
else
{
echo "<p>Mauvais code de vérification (Error : bad synchronisation code). Veuillez réessayer la mise à jour. Se référer au README pour plus d'informations sur la mise à jour.</p>";
}
echo "<p><a href='index.php'>Retourner à l'application (Back to index)</a></p></body></html>";
exit();
}
$liste_stations = unserialize(gzinflate(base64_decode(file_get_contents('data/stations'))));
?>
2014-01-24 18:55:06 +01:00
<div id="disclaimer">
<h2>Disclaimer</h2>
<p>Les temps rentrés sur cette page ne sont qu'indicatifs et sont fournis par les internautes eux-mêmes. Ils peuvent donc ne pas refléter les temps réels de parcours. En particulier, il est important de rappeler que le code de la route s'applique aussi aux vélos et que l'obtention d'un meilleur temps ne doit pas se faire au détriment du respect du code de la route.</p>
<p>Le respect des données personnelles étant particulièrement important, ce script ne conserve aucune information particulière si vous ne souhaitez pas en renseigner. Votre adresse IP est néanmoins stockée dans les logs de connexion au serveur, comme pour tout serveur web, conformément à l'article 6 de la LCEN.</p>
<p><a href="README.md">Plus d'informations sur DefiVelib</a></p>
</div>
2014-01-23 23:48:59 +01:00
<h2>Ajouter un trajet</h2>
<form method="post" action="index.php"> <!-- enctype="multipart/form-data"-->
<fieldset>
<legend>Trajet</legend>
2014-01-23 23:48:59 +01:00
<p><label name="start">Station de départ : </label>
<select name="start" id="start">
2014-01-23 23:48:59 +01:00
<?php
foreach($liste_stations as $key=>$station) {
2014-01-24 18:55:06 +01:00
if(!empty($_POST['start_search']) && $_POST['start_search'] == $key)
$selected = "selected";
else
$selected = "";
echo "<option value=\"".$key."\" ".$selected.">".$station['name']."</option>";
2014-01-23 23:48:59 +01:00
}
?>
</select>
</p>
<p><label for="end">Station d'arrivée : </label>
<select name="end" id="end">
2014-01-23 23:48:59 +01:00
<?php
foreach($liste_stations as $key=>$station) {
2014-01-24 18:55:06 +01:00
if(!empty($_POST['end_search']) && $_POST['end_search'] == $key)
$selected = "selected";
else
$selected = "";
echo "<option value=\"".$key."\" ".$selected.">".$station['name']."</option>";
2014-01-23 23:48:59 +01:00
}
?>
</select>
</p>
<p><label for="time_min">Durée du trajet : </label><input type="int" name="time_min" id="time_min" size="2"/>min <input type="int" name="time_sec" id="time_sec" size="2"/>s</p>
</fieldset>
<fieldset>
<legend>Informations</legend>
<p><label for="pseudo">Votre pseudo (optionnel) : </label><input type="text" name="pseudo" id="pseudo"/></p>
<!-- <p><label for="photo">Photo du ticket (? max) : </label><input type="file" name="photo" id="photo"></p>-->
</fieldset>
<p>
2014-01-24 18:55:06 +01:00
<input type="submit" value="Envoyer"/>
<input type="hidden" name="token" value="<?php echo $token; ?>"/>
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="2097152">-->
</p>
2014-01-23 23:48:59 +01:00
</form>
<h2><?php if($search) {?>Résultats<?php } else {?>Derniers trajets ajoutés<?php }?></h2>
2014-01-23 23:48:59 +01:00
<?php
if(!empty($data)) {
?>
<table>
<tr>
<th>Date</th>
2014-01-23 23:48:59 +01:00
<th>Départ</th>
<th>Arrivée</th>
<th>Temps</th>
<th>Pseudo</th>
2014-01-24 18:07:59 +01:00
<?php
if(!empty($_SESSION['admin'])) {
?>
<th>Supprimer</th>
<?php
}
?>
2014-01-23 23:48:59 +01:00
</tr>
<?php
if($search) {
$min = array();
$sec = array();
foreach($data as $key => $result) {
$min[$key] = $result['min'];
$sec[$key] = $result['sec'];
}
array_multisort($min, SORT_DESC, $sec, SORT_DESC, $data);
2014-01-24 18:07:59 +01:00
foreach($data as $key=>$result) {
if(!empty($_SESSION['admin'])) {
2014-01-24 18:55:06 +01:00
$delete = "<td><a href=\"?suppr=".$key."&token=".$token."\">Supprimer</a></td>";
2014-01-24 18:07:59 +01:00
}
else {
$delete = "";
}
echo "<tr><td>".date('d/m/Y à H:i', $result['date'])."</td><td>".htmlspecialchars($liste_stations[$result['start']]['name'])."</td><td>".htmlspecialchars($liste_stations[$result['end']]['name'])."</td><td>".(int) $result['min']."min ".(int) $result['sec']."s</td><td>".htmlspecialchars($result['pseudo'])."</td>".$delete."</tr>";
}
}
else {
for($i = count($data) - 1; $i >= max(count($data) - 10, 0); $i--) {
2014-01-24 18:07:59 +01:00
if(!empty($_SESSION['admin'])) {
2014-01-24 18:55:06 +01:00
$delete = "<td><a href=\"?suppr=".$i."&token=".$token."\">Supprimer</a></td>";
2014-01-24 18:07:59 +01:00
}
else {
$delete = "";
}
echo "<tr><td>".date('d/m/Y à H:i', $data[$i]['date'])."</td><td>".htmlspecialchars($liste_stations[$data[$i]['start']]['name'])."</td><td>".htmlspecialchars($liste_stations[$data[$i]['end']]['name'])."</td><td>".(int) $data[$i]['min']."min ".(int) $data[$i]['sec']."s</td><td>".htmlspecialchars($data[$i]['pseudo'])."</td>".$delete."</tr>";
}
2014-01-23 23:48:59 +01:00
}
?>
</table>
<?php
}
else {
?>
<p>Aucun trajet enregistré.</p>
<?php
}
?>
<h2>Recherche de trajets</h2>
<form method="post" action="index.php">
<fieldset>
<p><label name="start_search">Station de départ : </label>
<select name="start_search" id="start_search">
<?php
foreach($liste_stations as $key=>$station) {
2014-01-24 18:07:59 +01:00
if(!empty($_POST['start_search']) && $_POST['start_search'] == $key)
$selected = "selected";
else
$selected = "";
echo "<option value=\"".$key."\" ".$selected.">".$station['name']."</option>";
}
?>
</select>
</p>
<p><label for="end_search">Station d'arrivée : </label>
<select name="end_search" id="end_search">
<?php
foreach($liste_stations as $key=>$station) {
2014-01-24 18:07:59 +01:00
if(!empty($_POST['end_search']) && $_POST['end_search'] == $key)
$selected = "selected";
else
$selected = "";
echo "<option value=\"".$key."\" ".$selected.">".$station['name']."</option>";
}
?>
</select>
</p>
</fieldset>
<p>
2014-01-24 18:55:06 +01:00
<input type="submit" value="Rechercher"/>
<input type="hidden" name="token" value="<?php echo $token; ?>"/>
</p>
</form>
2014-01-24 18:07:59 +01:00
<?php
if(!empty($_SESSION['admin'])) {
?>
<p><a href="?deco=1">Déconnexion</a></p>
<?php
}
?>
2014-01-23 23:48:59 +01:00
</div>
</body>
</html>