Merge branch 'olivierperez/framadate-master' into develop
Conflicts: admin/index.php adminstuds.php app/classes/Framadate/Utils.php app/inc/config.template.php app/inc/init.php choix_autre.php choix_date.php composer.json composer.lock creation_sondage.php locale/de_DE/LC_MESSAGES/Studs.mo locale/de_DE/LC_MESSAGES/Studs.po locale/en_GB/LC_MESSAGES/Studs.mo locale/fr_FR/LC_MESSAGES/Studs.mo studs.php
This commit is contained in:
commit
c1d4bed4d5
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,12 +1,13 @@
|
||||
.htaccess
|
||||
admin/.htaccess
|
||||
admin/.htpasswd
|
||||
.htpasswd
|
||||
admin/logs_studs.txt
|
||||
composer.phar
|
||||
framanav
|
||||
nav
|
||||
app/inc/constants.php
|
||||
app/inc/config.php
|
||||
vendor
|
||||
cache/
|
||||
tpl_c/
|
||||
|
||||
# Temp files
|
||||
*~
|
||||
@ -15,3 +16,8 @@ vendor
|
||||
# Cache
|
||||
Thumbs.db
|
||||
|
||||
# IDE
|
||||
.settings/
|
||||
.project
|
||||
.idea/
|
||||
*.iml
|
||||
|
227
README.md
227
README.md
@ -7,112 +7,179 @@ If you want to work with us, **fork us on [git.framasoft.org](https://git.framas
|
||||
Si vous souhaitez travailler avec nous, **forkez-nous sur [git.framasoft.org](https://git.framasoft.org)**. (l'inscription n'est pas nécessaire, vous pouvez vous connecter avec votre compte Github)
|
||||
* * *
|
||||
|
||||
![English:](http://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Flag_of_the_United_Kingdom.svg/20px-Flag_of_the_United_Kingdom.svg.png)
|
||||
This software is governed by the CeCILL-B license. If a copy of this license
|
||||
is not distributed with this file, you can obtain one at
|
||||
[http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt](http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt)
|
||||
Framadate est un fork du projet STUdS : https://sourcesup.cru.fr/projects/studs/
|
||||
|
||||
Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
Authors of Framadate/OpenSondate: [Framasoft](https://git.framasoft.org/framasoft/framadate)
|
||||
Framadate est le projet qui motorise framadate.org pour framasoft.org
|
||||
|
||||
![Français :](http://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Flag_of_France.svg/20px-Flag_of_France.svg.png)
|
||||
Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
[http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt](http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt)
|
||||
Les auteurs principaux de Framadate sont :
|
||||
- Simon LEBLANC
|
||||
- Pierre-Yves GOSSET
|
||||
|
||||
Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
Auteurs de Framadate/OpenSondage : [Framasoft](https://git.framasoft.org/framasoft/framadate)
|
||||
Les auteurs principaux du projet STUdS sont :
|
||||
- Guilhem BORGHESI
|
||||
- Raphaël DROZ
|
||||
|
||||
* * *
|
||||
|
||||
#Framadate
|
||||
[Framadate](https://framadate.org) est un fork du projet [STUdS](https://sourcesup.cru.fr/projects/studs/).
|
||||
Il est développé par l'association [Framasoft](http://framasoft.org).
|
||||
==========================================================================
|
||||
|
||||
##Fichiers de l'application
|
||||
Université de Strasbourg - Direction Informatique
|
||||
Auteur : Guilhem BORGHESI
|
||||
Création : Février 2008
|
||||
|
||||
### Administration
|
||||
* `/admin`
|
||||
borghesi@unistra.fr
|
||||
|
||||
Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
|
||||
respectant les principes de diffusion des logiciels libres. Vous pouvez
|
||||
utiliser, modifier et/ou redistribuer ce programme sous les conditions
|
||||
de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
|
||||
sur le site "http://www.cecill.info".
|
||||
|
||||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
|
||||
pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
|
||||
termes. Vous pouvez trouver une copie de la licence dans le fichier LICENCE.
|
||||
|
||||
==========================================================================
|
||||
|
||||
Université de Strasbourg - Direction Informatique
|
||||
Author : Guilhem BORGHESI
|
||||
Creation : Feb 2008
|
||||
|
||||
borghesi@unistra.fr
|
||||
|
||||
This software is governed by the CeCILL-B license under French law and
|
||||
abiding by the rules of distribution of free software. You can use,
|
||||
modify and/ or redistribute the software under the terms of the CeCILL-B
|
||||
license as circulated by CEA, CNRS and INRIA at the following URL
|
||||
"http://www.cecill.info".
|
||||
|
||||
The fact that you are presently reading this means that you have had
|
||||
knowledge of the CeCILL-B license and that you accept its terms. You can
|
||||
find a copy of this license in the file LICENSE.
|
||||
|
||||
==========================================================================
|
||||
|
||||
=============================================================================
|
||||
Fichiers de l'application
|
||||
=============================================================================
|
||||
|
||||
index.php
|
||||
La page d'accueil de STUdS
|
||||
studs.php
|
||||
La page de présentation de sondage
|
||||
adminstuds.php
|
||||
La page d'administration réservée à l'auteur du sondage
|
||||
infos_sondage.php
|
||||
La page (1/2) de création de sondage récupérant les informations générales
|
||||
choix_date.php
|
||||
La page de création (2/2) pour un sondage pour déterminer une date
|
||||
choix_autre.php
|
||||
La page de création (2/2) pour un sondage sur un sujet quelconque
|
||||
creation_sondage.php
|
||||
Le fichier qui récupérent les informations des pages précédentes pour procéder à l'insertion du nouveau sondage dans la base PostgreSQL
|
||||
style.css
|
||||
Le fichier CSS de style pour toute l'application
|
||||
app/inc/constants.php
|
||||
Le fichier contenant les constantes à changer en fonction de la machine locale
|
||||
app/inc/functions.php
|
||||
Le fichier contenant quelques fonctions récurrentes de l'application
|
||||
app/inc/i18n.php
|
||||
Le fichier contenant quelques fonctions récurrentes de l'application relatives à l'internationalisation
|
||||
README
|
||||
Ce fichier
|
||||
INSTALL
|
||||
Le fichier contenant les informations d'installation sur l'application
|
||||
CHANGELOG
|
||||
Le fichier contenant toutes les modifications de l'application entre les différentes versions
|
||||
contacts.php
|
||||
La page permettant aux usagers de poser une question à l'administrateur de l'application
|
||||
apropos.php
|
||||
La page expliquant les détails techniques relatifs à l'application et les dernieres modifications et celles à venir sur l'application
|
||||
bandeaux.php
|
||||
Le fichier contenant tous les bandeaux des pages PHP de l'application
|
||||
favicon.ico
|
||||
L'icone de favoris de l'application
|
||||
sources.php
|
||||
La page qui propose les sources de l'application
|
||||
exportics.php
|
||||
Le fichier d'export de la meilleure date au format iCAL (fichier .ICS)
|
||||
exportcsv.php
|
||||
Le fichier d'export de tous le tableau des participants avec leurs réponses dans un tableur (format .CSV)
|
||||
exportpdf.php
|
||||
Le fichier d'export de la lettre de convocation que le créateur du sondage pourra envoyer aux participants (format .PDF)
|
||||
|
||||
admin/
|
||||
Le répertoire réservé à l'administrateur de l'application
|
||||
* `admin/index.php`
|
||||
admin/.htaccess
|
||||
Le fichier gérant les droits restreints du répertoire ADMIN
|
||||
admin/.htpasswd
|
||||
Le fichier contenant les passwd des logins ayant accès au répertoire ADMIN
|
||||
admin/index.php
|
||||
La page présentant tous les sondages actuellement dans la base à l'administrateur
|
||||
* `admin/log_studs.txt`
|
||||
admin/log_studs.txt
|
||||
Le fichier contenant un historique de toutes les creations/suppressions de sondage dans la base
|
||||
|
||||
* `install/` (pas utilisé - en développement)
|
||||
Le répertoire qui contient les scripts chargés de simplifier la procédure d'installation
|
||||
* `scripts/` (pas utilisé)
|
||||
Le répertoire qui contient quelques vieux scripts pour la maintenance de l'application
|
||||
errors/
|
||||
Le répertoire contenant toutes les pages d'erreurs
|
||||
errors/error-forbidden.php
|
||||
La page qui indique dans la charte graphique de l'application l'erreur "501 forbidden"
|
||||
errors/maintenance.php
|
||||
La page qui indique que l'application est en maintenance temporaire
|
||||
|
||||
### Application
|
||||
* `app/inc/constants.php.template`
|
||||
Le fichier contenant les constantes à changer en fonction de la machine locale
|
||||
* `app/classes/Framadate/Utils.php`
|
||||
Le fichier contenant quelques fonctions récurrentes de l'application
|
||||
* `app/inc/i18n.php`
|
||||
Le fichier contenant quelques fonctions récurrentes de l'application relatives à l'internationalisation
|
||||
* `app/inc/init.php`
|
||||
Le fichier qui charge les dépendances et ouvre la connexion à la base de données
|
||||
export/
|
||||
Le répertoire qui contient tous les exports ICS
|
||||
|
||||
* `css/`
|
||||
Les fichiers CSS de l'application (dont ceux de Bootstrap)
|
||||
* `fonts/`
|
||||
Les fichiers des icônes de Bootstrap
|
||||
* `images/`
|
||||
Logo et images de la page d'accueil
|
||||
* `js/`
|
||||
Les fichiers javascript de l'application (dont ceux de Bootstrap et de jQuery)
|
||||
iCalcreator/
|
||||
Le répertoire qui contient les librairies d'export en iCal
|
||||
|
||||
* `locale/`
|
||||
php2pdf/
|
||||
Le répertoire qui contient les librairies d'export en PDF
|
||||
|
||||
scripts/
|
||||
Le répertoire qui contient tous les scripts de l'application
|
||||
|
||||
sources/
|
||||
Le répertoire qui contient les sources de l'application disponible sur la page sources.php
|
||||
|
||||
locale/
|
||||
Le répertoire qui contient les fichiers de traduction modifiables (.po) et compilés (.mo)
|
||||
au format gettext
|
||||
|
||||
* `index.php`
|
||||
La page d'accueil de STUdS
|
||||
* `studs.php`
|
||||
La page de présentation de sondage
|
||||
* `adminstuds.php`
|
||||
La page d'administration réservée à l'auteur du sondage
|
||||
* `infos_sondage.php`
|
||||
La page (1/2) de création de sondage récupérant les informations générales
|
||||
* `choix_date.php`
|
||||
La page de création (2/2) pour un sondage pour déterminer une date
|
||||
* `choix_autre.php`
|
||||
La page de création (2/2) pour un sondage sur un sujet quelconque
|
||||
* `creation_sondage.php`
|
||||
Le fichier qui récupérent les informations des pages précédentes pour procéder à l'insertion du nouveau sondage dans la base PostgreSQL
|
||||
=============================================================================
|
||||
Validations des pages
|
||||
=============================================================================
|
||||
|
||||
* `bandeaux.php`
|
||||
Le fichier contenant les éléments de l'entête et du pied de page de l'application
|
||||
* `exportcsv.php`
|
||||
Le fichier d'export de tous le tableau des participants avec leurs réponses dans un tableur (format .CSV)
|
||||
* `favicon.ico`
|
||||
L'icone de favoris de l'application
|
||||
Toutes les pages de STUdS sont validées HTML 4.01 Strict.
|
||||
La CSS de STUdS est validée CSS 2.1.
|
||||
|
||||
### Infos
|
||||
* `AUTHORS.md`
|
||||
Liste des principaux développeurs du logiciel
|
||||
* `README.md`
|
||||
Ce fichier
|
||||
* `INSTALL.md`
|
||||
Le fichier contenant les informations d'installation sur l'application
|
||||
* `CHANGELOG.md`
|
||||
Le fichier contenant la liste des principale modifications de l'application entre les différentes versions
|
||||
=============================================================================
|
||||
Technologies utilisées
|
||||
=============================================================================
|
||||
|
||||
##Technologies utilisées
|
||||
|
||||
- PHP 5.4.4, php-adodb, php-gettext, composer
|
||||
- Bootstrap, jQuery, Bootstrap Datepicker
|
||||
- MySQL
|
||||
- Nginx, Apache
|
||||
- PHP 5.4.4, php-fpdf, php-adodb, php-gettext
|
||||
- PostgreSQL, mysql
|
||||
- Apache
|
||||
- iCalcreator
|
||||
- POedit
|
||||
- Icônes : Deleket (http://deleket.deviantart.com/) et DryIcons (http://dryicons.com)
|
||||
|
||||
##Compatibilités des navigateurs
|
||||
(Dernière mise à jour le 21 avril 2014)
|
||||
=============================================================================
|
||||
Compatibilités des navigateurs
|
||||
Dernière mise à jour le 21 avril 2014
|
||||
=============================================================================
|
||||
|
||||
- Firefox : Ubuntu 13.10/FF28
|
||||
- Chrome : Ubuntu 13.10/Chromium33
|
||||
- Opera (non testé)
|
||||
- Konqueror
|
||||
- Links (non testé, inutile)
|
||||
- Safari (non testé)
|
||||
- IE : Win7/IE9
|
||||
|
||||
-----------------
|
||||
Janvier 2008
|
||||
Guilhem BORGHESI
|
||||
Université de Strasbourg
|
||||
|
||||
Mai 2010
|
||||
Raphaël DROZ, raphael.droz@gmail.com
|
||||
|
||||
|
@ -16,100 +16,9 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
session_start();
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
include_once __DIR__ . '/../bandeaux.php';
|
||||
require_once '../app/inc/init.php';
|
||||
|
||||
// Ce fichier index.php se trouve dans le sous-repertoire ADMIN de Studs. Il sert à afficher l'intranet de studs
|
||||
// pour modifier les sondages directement sans avoir reçu les mails. C'est l'interface d'aministration
|
||||
// de l'application.
|
||||
|
||||
// Affichage des balises standards
|
||||
Utils::print_header( _("Polls administrator") );
|
||||
bandeau_titre(_("Polls administrator"));
|
||||
|
||||
$sondage=$connect->Execute("select * from sondage");
|
||||
|
||||
echo'
|
||||
<form action="' . Utils::get_server_name() . 'admin/index.php" method="POST">'."\n";
|
||||
// Test et affichage du bouton de confirmation en cas de suppression de sondage
|
||||
while($dsondage = $sondage->FetchNextObject(false)) {
|
||||
if (Utils::issetAndNoEmpty('supprimersondage'.$dsondage->id_sondage) === true) {
|
||||
echo '
|
||||
<div class="alert alert-warning text-center">
|
||||
<h3>'. _("Confirm removal of the poll ") .'"'.$dsondage->id_sondage.'</h3>
|
||||
<p><button class="btn btn-default" type="submit" value="1" name="annullesuppression">'._("Keep this poll!").'</button>
|
||||
<button type="submit" name="confirmesuppression'.$dsondage->id_sondage.'" value="1" class="btn btn-danger">'._("Remove this poll!").'</button></p>
|
||||
</div>';
|
||||
}
|
||||
|
||||
// Traitement de la confirmation de suppression
|
||||
if (Utils::issetAndNoEmpty('confirmesuppression'.$dsondage->id_sondage) === true) {
|
||||
// On inclut la routine de suppression
|
||||
$date=date('H:i:s d/m/Y');
|
||||
|
||||
if (Utils::remove_sondage($connect, $dsondage->id_sondage)) {
|
||||
// ecriture des traces dans le fichier de logs
|
||||
error_log($date . " SUPPRESSION: $dsondage->id_sondage\t$dsondage->format\t$dsondage->nom_admin\t$dsondage->mail_admin\n", 3, 'logs_studs.txt');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sondage=$connect->Execute("select * from sondage WHERE date_fin > DATE_SUB(now(), INTERVAL 3 MONTH) ORDER BY date_fin ASC");
|
||||
$nbsondages=$sondage->RecordCount();
|
||||
|
||||
$btn_logs = (is_readable('logs_studs.txt')) ? '<a role="button" class="btn btn-default btn-xs pull-right" href="'.str_replace('/admin','', Utils::get_server_name()).'admin/logs_studs.txt">'. _("Logs") .'</a>' : '';
|
||||
|
||||
echo '<p>' . $nbsondages. ' ' . _("polls in the database at this time") . $btn_logs .'</p>'."\n";
|
||||
|
||||
// tableau qui affiche tous les sondages de la base
|
||||
echo '<table class="table table-bordered">
|
||||
<tr align="center">
|
||||
<th scope="col">'. _("Poll ID") .'</th>
|
||||
<th scope="col">'. _("Format") .'</th>
|
||||
<th scope="col">'. _("Title") .'</th>
|
||||
<th scope="col">'. _("Author") .'</th>
|
||||
<th scope="col">'. _("Email") .'</th>
|
||||
<th scope="col">'. _("Expiration's date") .'</th>
|
||||
<th scope="col">'. _("Users") .'</th>
|
||||
<th scope="col" colspan="3">'. _("Actions") .'</th>
|
||||
</tr>'."\n";
|
||||
|
||||
$i = 0;
|
||||
while($dsondage = $sondage->FetchNextObject(false)) {
|
||||
/* possible en 1 bonne requête dans $sondage */
|
||||
$sujets=$connect->Execute( "select * from sujet_studs where id_sondage='$dsondage->id_sondage'");
|
||||
$dsujets=$sujets->FetchObject(false);
|
||||
|
||||
$user_studs=$connect->Execute( "select * from user_studs where id_sondage='$dsondage->id_sondage'");
|
||||
$nbuser=$user_studs->RecordCount();
|
||||
|
||||
echo '
|
||||
<tr align="center">
|
||||
<td>'.$dsondage->id_sondage.'</td>
|
||||
<td>'.$dsondage->format.'</td>
|
||||
<td>'. stripslashes($dsondage->titre).'</td>
|
||||
<td>'.stripslashes($dsondage->nom_admin).'</td>
|
||||
<td>'.stripslashes($dsondage->mail_admin).'</td>';
|
||||
|
||||
if (strtotime($dsondage->date_fin) > time()) {
|
||||
echo '
|
||||
<td>'.date("d/m/y",strtotime($dsondage->date_fin)).'</td>';
|
||||
} else {
|
||||
echo '
|
||||
<td><span class="text-danger">'.date("d/m/y",strtotime($dsondage->date_fin)).'</span></td>';
|
||||
}
|
||||
echo '
|
||||
<td>'.$nbuser.'</td>
|
||||
<td><a href="' . Utils::getUrlSondage($dsondage->id_sondage) . '" class="btn btn-link" title="'. _("See the poll") .'"><span class="glyphicon glyphicon-eye-open"></span><span class="sr-only">' . _("See the poll") . '</span></a></td>
|
||||
<td><a href="' . Utils::getUrlSondage($dsondage->id_sondage_admin, true) . '" class="btn btn-link" title="'. _("Change the poll") .'"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _("Change the poll") . '</span></a></td>
|
||||
<td><button type="submit" name="supprimersondage'.$dsondage->id_sondage.'" value="'. _("Remove the poll") .'" class="btn btn-link" title="'. _("Remove the poll") .'"><span class="glyphicon glyphicon-trash text-danger"></span><span class="sr-only">' . _("Remove the poll") . '</span></td>
|
||||
</tr>'."\n";
|
||||
$i++;
|
||||
}
|
||||
|
||||
echo '</table></form>'."\n";
|
||||
|
||||
bandeau_pied(true);
|
||||
$smarty->assign('title', _('Administration'));
|
||||
$smarty->assign('logsAreReadable', is_readable('../' . LOG_FILE));
|
||||
$smarty->display('admin/index.tpl');
|
28
admin/logs.php
Normal file
28
admin/logs.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
require_once '../app/inc/init.php';
|
||||
|
||||
ob_start();
|
||||
is_readable('../' . LOG_FILE) ? readfile('../' . LOG_FILE) : null;
|
||||
$content = ob_get_clean();
|
||||
|
||||
$smarty->assign('title', _('Administration'));
|
||||
$smarty->assign('logs', $content);
|
||||
$smarty->display('admin/logs.tpl');
|
107
admin/migration.php
Normal file
107
admin/migration.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Migration\From_0_0_to_0_8_Migration;
|
||||
use Framadate\Migration\From_0_8_to_0_9_Migration;
|
||||
use Framadate\Migration\From_0_9_to_0_9_1_Migration;
|
||||
use Framadate\Migration\Migration;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
set_time_limit(300);
|
||||
|
||||
// List a Migration sub classes to execute
|
||||
$migrations = [
|
||||
new From_0_0_to_0_8_Migration(),
|
||||
new From_0_8_to_0_9_Migration(),
|
||||
new From_0_9_to_0_9_1_Migration()
|
||||
];
|
||||
// ---------------------------------------
|
||||
|
||||
// Check if MIGRATION_TABLE already exists
|
||||
$tables = $connect->allTables();
|
||||
$pdo = $connect->getPDO();
|
||||
$prefixedMigrationTable = Utils::table(MIGRATION_TABLE);
|
||||
|
||||
if (!in_array($prefixedMigrationTable, $tables)) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . $prefixedMigrationTable . '` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` TEXT NOT NULL,
|
||||
`execute_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE = MyISAM
|
||||
DEFAULT CHARSET = utf8;');
|
||||
}
|
||||
|
||||
$selectStmt = $pdo->prepare('SELECT id FROM ' . $prefixedMigrationTable . ' WHERE name=?');
|
||||
$insertStmt = $pdo->prepare('INSERT INTO ' . $prefixedMigrationTable . ' (name) VALUES (?)');
|
||||
$countSucceeded = 0;
|
||||
$countFailed = 0;
|
||||
$countSkipped = 0;
|
||||
|
||||
// Loop on every Migration sub classes
|
||||
$success = [];
|
||||
$fail = [];
|
||||
foreach ($migrations as $migration) {
|
||||
$className = get_class($migration);
|
||||
|
||||
// Check if $className is a Migration sub class
|
||||
if (!$migration instanceof Migration) {
|
||||
$smarty->assign('error', 'The class ' . $className . ' is not a sub class of Framadate\\Migration\\Migration.');
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check if the Migration is already executed
|
||||
$selectStmt->execute([$className]);
|
||||
$executed = $selectStmt->rowCount();
|
||||
$selectStmt->closeCursor();
|
||||
|
||||
if (!$executed && $migration->preCondition($pdo)) {
|
||||
$migration->execute($pdo);
|
||||
if ($insertStmt->execute([$className])) {
|
||||
$countSucceeded++;
|
||||
$success[] = $migration->description();
|
||||
} else {
|
||||
$countFailed++;
|
||||
$fail[] = $migration->description();
|
||||
}
|
||||
} else {
|
||||
$countSkipped++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$countTotal = $countSucceeded + $countFailed + $countSkipped;
|
||||
|
||||
$smarty->assign('success', $success);
|
||||
$smarty->assign('fail', $fail);
|
||||
|
||||
$smarty->assign('countSucceeded', $countSucceeded);
|
||||
$smarty->assign('countFailed', $countFailed);
|
||||
$smarty->assign('countSkipped', $countSkipped);
|
||||
$smarty->assign('countTotal', $countTotal);
|
||||
$smarty->assign('time', $total_time = round((microtime(true)-$_SERVER['REQUEST_TIME_FLOAT']), 4));
|
||||
|
||||
$smarty->assign('title', _('Migration'));
|
||||
|
||||
$smarty->display('admin/migration.tpl');
|
78
admin/polls.php
Normal file
78
admin/polls.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\AdminPollService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Services\SuperAdminService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
include_once __DIR__ . '/../bandeaux.php';
|
||||
|
||||
const POLLS_PER_PAGE = 30;
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
$polls = null;
|
||||
$poll_to_delete = null;
|
||||
|
||||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$superAdminService = new SuperAdminService($connect);
|
||||
$securityService = new SecurityService();
|
||||
|
||||
/* GET */
|
||||
/*-----*/
|
||||
$page = (int)filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
|
||||
$page = ($page >= 1) ? $page : 1;
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if (!empty($_POST['delete_poll']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||
$delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll_to_delete = $pollService->findById($delete_id);
|
||||
}
|
||||
|
||||
// Traitement de la confirmation de suppression
|
||||
if (!empty($_POST['delete_confirm']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||
$poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$adminPollService->deleteEntirePoll($poll_id);
|
||||
}
|
||||
|
||||
$found = $superAdminService->findAllPolls($page-1, POLLS_PER_PAGE);
|
||||
$polls = $found['polls'];
|
||||
$count = $found['count'];
|
||||
|
||||
// Assign data to template
|
||||
$smarty->assign('polls', $polls);
|
||||
$smarty->assign('count', $count);
|
||||
$smarty->assign('page', $page);
|
||||
$smarty->assign('pages', ceil($count / POLLS_PER_PAGE));
|
||||
$smarty->assign('poll_to_delete', $poll_to_delete);
|
||||
$smarty->assign('crsf', $securityService->getToken('admin'));
|
||||
|
||||
$smarty->display('admin/polls.tpl');
|
56
admin/purge.php
Normal file
56
admin/purge.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
include_once __DIR__ . '/../bandeaux.php';
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
$message = null;
|
||||
|
||||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
$securityService = new SecurityService();
|
||||
|
||||
/* POST */
|
||||
/*-----*/
|
||||
$action = filter_input(INPUT_POST, 'action', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]);
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if ($action === 'purge' && $securityService->checkCsrf('admin', $_POST['csrf'])) {
|
||||
$count = $purgeService->purgeOldPolls();
|
||||
$message = _('Purged:') . ' ' . $count;
|
||||
}
|
||||
|
||||
// Assign data to template
|
||||
$smarty->assign('message', $message);
|
||||
$smarty->assign('crsf', $securityService->getToken('admin'));
|
||||
|
||||
$smarty->display('admin/purge.tpl');
|
1484
adminstuds.php
1484
adminstuds.php
File diff suppressed because it is too large
Load Diff
59
app/classes/Framadate/Choice.php
Normal file
59
app/classes/Framadate/Choice.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
class Choice
|
||||
{
|
||||
/**
|
||||
* Name of the Choice
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* All availables slots for this Choice.
|
||||
*/
|
||||
private $slots;
|
||||
|
||||
public function __construct($name='')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->slots = array();
|
||||
}
|
||||
|
||||
public function addSlot($slot)
|
||||
{
|
||||
$this->slots[] = $slot;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getSlots()
|
||||
{
|
||||
return $this->slots;
|
||||
}
|
||||
|
||||
static function compare(Choice $a, Choice $b)
|
||||
{
|
||||
return strcmp($a->name, $b->name);
|
||||
}
|
||||
|
||||
}
|
81
app/classes/Framadate/Form.php
Normal file
81
app/classes/Framadate/Form.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
class Form
|
||||
{
|
||||
|
||||
public $title;
|
||||
public $description;
|
||||
public $admin_name;
|
||||
public $admin_mail;
|
||||
public $format;
|
||||
public $end_date;
|
||||
public $choix_sondage;
|
||||
|
||||
/**
|
||||
* Tells if users can modify their choices.
|
||||
*/
|
||||
public $editable;
|
||||
|
||||
/**
|
||||
* If true, notify poll administrator when new vote is made.
|
||||
*/
|
||||
public $receiveNewVotes;
|
||||
|
||||
/**
|
||||
* If true, notify poll administrator when new comment is posted.
|
||||
*/
|
||||
public $receiveNewComments;
|
||||
|
||||
/**
|
||||
* List of available choices
|
||||
*/
|
||||
private $choices;
|
||||
|
||||
public function __construct(){
|
||||
$this->editable = true;
|
||||
$this->clearChoices();
|
||||
}
|
||||
|
||||
public function clearChoices() {
|
||||
$this->choices = array();
|
||||
}
|
||||
|
||||
public function addChoice(Choice $choice)
|
||||
{
|
||||
$this->choices[] = $choice;
|
||||
}
|
||||
|
||||
public function getChoices()
|
||||
{
|
||||
return $this->choices;
|
||||
}
|
||||
|
||||
public function sortChoices()
|
||||
{
|
||||
usort($this->choices, array('Framadate\Choice', 'compare'));
|
||||
}
|
||||
|
||||
public function lastChoice()
|
||||
{
|
||||
return end($this->choices);
|
||||
}
|
||||
|
||||
}
|
314
app/classes/Framadate/FramaDB.php
Normal file
314
app/classes/Framadate/FramaDB.php
Normal file
@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
use PDO;
|
||||
|
||||
class FramaDB {
|
||||
/**
|
||||
* PDO Object, connection to database.
|
||||
*/
|
||||
private $pdo = null;
|
||||
|
||||
function __construct($connection_string, $user, $password) {
|
||||
$this->pdo = new \PDO($connection_string, $user, $password);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PDO Connection to database
|
||||
*/
|
||||
function getPDO() {
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all tables in database.
|
||||
*
|
||||
* @return array The array of table names
|
||||
*/
|
||||
function allTables() {
|
||||
$result = $this->pdo->query('SHOW TABLES');
|
||||
$schemas = $result->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
return $schemas;
|
||||
}
|
||||
|
||||
function prepare($sql) {
|
||||
return $this->pdo->prepare($sql);
|
||||
}
|
||||
|
||||
function beginTransaction() {
|
||||
$this->pdo->beginTransaction();
|
||||
}
|
||||
|
||||
function commit() {
|
||||
$this->pdo->commit();
|
||||
}
|
||||
|
||||
function rollback() {
|
||||
$this->pdo->rollback();
|
||||
}
|
||||
|
||||
function errorCode() {
|
||||
return $this->pdo->errorCode();
|
||||
}
|
||||
|
||||
function errorInfo() {
|
||||
return $this->pdo->errorInfo();
|
||||
}
|
||||
|
||||
function query($sql) {
|
||||
return $this->pdo->query($sql);
|
||||
}
|
||||
|
||||
function findPollById($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE id = ?');
|
||||
|
||||
$prepared->execute([$poll_id]);
|
||||
$poll = $prepared->fetch();
|
||||
$prepared->closeCursor();
|
||||
|
||||
return $poll;
|
||||
}
|
||||
|
||||
function updatePoll($poll) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=FROM_UNIXTIME(?), active=?, editable=? WHERE id = ?');
|
||||
|
||||
return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->id]);
|
||||
}
|
||||
|
||||
function allCommentsByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('comment') . '` WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute(array($poll_id));
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
function allUserVotesByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute(array($poll_id));
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
function allSlotsByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY title');
|
||||
$prepared->execute(array($poll_id));
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
function insertDefaultVote($poll_id, $insert_position) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTRING(choices, 1, ?), "0", SUBSTRING(choices, ?)) WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
|
||||
}
|
||||
|
||||
function insertVote($poll_id, $name, $choices) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices) VALUES (?,?,?)');
|
||||
$prepared->execute([$poll_id, $name, $choices]);
|
||||
|
||||
$newVote = new \stdClass();
|
||||
$newVote->poll_id = $poll_id;
|
||||
$newVote->id = $this->pdo->lastInsertId();
|
||||
$newVote->name = $name;
|
||||
$newVote->choices = $choices;
|
||||
|
||||
return $newVote;
|
||||
}
|
||||
|
||||
function deleteVote($poll_id, $vote_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id, $vote_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all votes of a given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the given poll.
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function deleteVotesByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all votes made on given moment index.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $index int The index of the vote into the poll
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function deleteVotesByIndex($poll_id, $index) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$index, $index + 2, $poll_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the slot into poll for a given datetime.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime int The datetime of the slot
|
||||
* @return mixed Object The slot found, or null
|
||||
*/
|
||||
function findSlotByPollIdAndDatetime($poll_id, $datetime) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND SUBSTRING_INDEX(title, \'@\', 1) = ?');
|
||||
|
||||
$prepared->execute([$poll_id, $datetime]);
|
||||
$slot = $prepared->fetch();
|
||||
$prepared->closeCursor();
|
||||
|
||||
return $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new slot into a given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $title mixed The title of the slot
|
||||
* @param $moments mixed|null The moments joined with ","
|
||||
* @return bool true if action succeeded
|
||||
*/
|
||||
function insertSlot($poll_id, $title, $moments) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('slot') . '` (poll_id, title, moments) VALUES (?,?,?)');
|
||||
|
||||
return $prepared->execute([$poll_id, $title, $moments]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a slot into a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime int The datetime of the slot to update
|
||||
* @param $newMoments mixed The new moments
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function updateSlot($poll_id, $datetime, $newMoments) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('slot') . '` SET moments = ? WHERE poll_id = ? AND title = ?');
|
||||
|
||||
return $prepared->execute([$newMoments, $poll_id, $datetime]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a entire slot from a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime mixed The datetime of the slot
|
||||
*/
|
||||
function deleteSlot($poll_id, $datetime) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND title = ?');
|
||||
$prepared->execute([$poll_id, $datetime]);
|
||||
}
|
||||
|
||||
function deleteSlotsByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all comments of a given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the given poll.
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function deleteCommentsByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
}
|
||||
|
||||
function updateVote($poll_id, $vote_id, $name, $choices) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = ?, name = ? WHERE poll_id = ? AND id = ?');
|
||||
|
||||
return $prepared->execute([$choices, $name, $poll_id, $vote_id]);
|
||||
}
|
||||
|
||||
function insertComment($poll_id, $name, $comment) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('comment') . '` (poll_id, name, comment) VALUES (?,?,?)');
|
||||
|
||||
return $prepared->execute([$poll_id, $name, $comment]);
|
||||
}
|
||||
|
||||
function deleteComment($poll_id, $comment_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id, $comment_id]);
|
||||
}
|
||||
|
||||
function deletePollById($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('poll') . '` WHERE id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find old polls. Limit: 20.
|
||||
*
|
||||
* @return array Array of old polls
|
||||
*/
|
||||
public function findOldPolls() {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE DATE_ADD(`end_date`, INTERVAL ' . PURGE_DELAY . ' DAY) < NOW() AND `end_date` != 0 LIMIT 20');
|
||||
$prepared->execute([]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $start int The index of the first poll to return
|
||||
* @param $limit int The limit size
|
||||
* @return array
|
||||
*/
|
||||
public function findAllPolls($start, $limit) {
|
||||
// Polls
|
||||
$prepared = $this->prepare('
|
||||
SELECT p.*,
|
||||
(SELECT count(1) FROM `' . Utils::table('vote') . '` v WHERE p.id=v.poll_id) votes
|
||||
FROM ' . Utils::table('poll') . ' p
|
||||
ORDER BY p.title ASC
|
||||
LIMIT :start, :limit');
|
||||
$prepared->bindParam(':start', $start, PDO::PARAM_INT);
|
||||
$prepared->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||
$prepared->execute();
|
||||
$polls = $prepared->fetchAll();
|
||||
|
||||
// Total count
|
||||
$stmt = $this->query('SELECT count(1) nb FROM `' . Utils::table('poll') . '`');
|
||||
$count = $stmt->fetch();
|
||||
$stmt->closeCursor();
|
||||
|
||||
return ['polls' => $polls, 'count' => $count->nb];
|
||||
}
|
||||
|
||||
public function countVotesByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT count(1) nb FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
|
||||
|
||||
$prepared->execute([$poll_id]);
|
||||
$result = $prepared->fetch();
|
||||
$prepared->closeCursor();
|
||||
|
||||
return $result->nb;
|
||||
}
|
||||
}
|
32
app/classes/Framadate/Message.php
Normal file
32
app/classes/Framadate/Message.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
class Message {
|
||||
|
||||
var $type;
|
||||
var $message;
|
||||
|
||||
function __construct($type, $message) {
|
||||
$this->type = $type;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace Framadate\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
class From_0_0_to_0_8_Migration implements Migration {
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "First installation of the Framadate application (v0.8)";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if there is no tables but the MIGRATION_TABLE one
|
||||
$diff = array_diff($tables, [Utils::table(MIGRATION_TABLE)]);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `sondage` (
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`commentaires` text,
|
||||
`mail_admin` varchar(128) DEFAULT NULL,
|
||||
`nom_admin` varchar(64) DEFAULT NULL,
|
||||
`titre` text,
|
||||
`id_sondage_admin` char(24) DEFAULT NULL,
|
||||
`date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`date_fin` timestamp NOT NULL DEFAULT \'0000-00-00 00:00:00\',
|
||||
`format` varchar(2) DEFAULT NULL,
|
||||
`mailsonde` tinyint(1) DEFAULT \'0\',
|
||||
`statut` int(11) NOT NULL DEFAULT \'1\' COMMENT \'1 = actif ; 0 = inactif ; \',
|
||||
UNIQUE KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;');
|
||||
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `sujet_studs` (
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`sujet` text,
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;');
|
||||
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `comments` (
|
||||
`id_comment` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`usercomment` text,
|
||||
PRIMARY KEY (`id_comment`),
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;');
|
||||
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `user_studs` (
|
||||
`id_users` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`nom` varchar(64) NOT NULL,
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`reponses` text NOT NULL,
|
||||
PRIMARY KEY (`id_users`),
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;');
|
||||
}
|
||||
}
|
273
app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php
Normal file
273
app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
namespace Framadate\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This class executes the aciton in database to migrate data from version 0.8 to 0.9.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
*/
|
||||
class From_0_8_to_0_9_Migration implements Migration {
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "From 0.8 to 0.9";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.8 are presents
|
||||
$diff = array_diff(['sondage', 'sujet_studs', 'comments', 'user_studs'], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->createPollTable($pdo);
|
||||
$this->createCommentTable($pdo);
|
||||
$this->createSlotTable($pdo);
|
||||
$this->createVoteTable($pdo);
|
||||
|
||||
$pdo->beginTransaction();
|
||||
$this->migrateFromSondageToPoll($pdo);
|
||||
$this->migrateFromCommentsToComment($pdo);
|
||||
$this->migrateFromSujetStudsToSlot($pdo);
|
||||
$this->migrateFromUserStudsToVote($pdo);
|
||||
$pdo->commit();
|
||||
|
||||
$this->dropOldTables($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function createPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('poll') . '` (
|
||||
`id` CHAR(16) NOT NULL,
|
||||
`admin_id` CHAR(24) NOT NULL,
|
||||
`title` TEXT NOT NULL,
|
||||
`description` TEXT,
|
||||
`admin_name` VARCHAR(64) DEFAULT NULL,
|
||||
`admin_mail` VARCHAR(128) DEFAULT NULL,
|
||||
`creation_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`end_date` TIMESTAMP NOT NULL DEFAULT \'0000-00-00 00:00:00\',
|
||||
`format` VARCHAR(1) DEFAULT NULL,
|
||||
`editable` TINYINT(1) DEFAULT \'0\',
|
||||
`receiveNewVotes` TINYINT(1) DEFAULT \'0\',
|
||||
`active` TINYINT(1) DEFAULT \'1\',
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8');
|
||||
}
|
||||
|
||||
private function migrateFromSondageToPoll(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`id_sondage_admin`,
|
||||
`titre`,
|
||||
`commentaires`,
|
||||
`nom_admin`,
|
||||
`mail_admin`,
|
||||
`date_creation`,
|
||||
`date_fin`,
|
||||
SUBSTR(`format`, 1, 1) AS `format`,
|
||||
CASE SUBSTR(`format`, 2, 1)
|
||||
WHEN \'+\' THEN 1
|
||||
ELSE 0 END AS `editable`,
|
||||
`mailsonde`,
|
||||
CASE SUBSTR(`format`, 2, 1)
|
||||
WHEN \'-\' THEN 0
|
||||
ELSE 1 END AS `active`
|
||||
FROM sondage');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('poll') . '`
|
||||
(`id`, `admin_id`, `title`, `description`, `admin_name`, `admin_mail`, `creation_date`, `end_date`, `format`, `editable`, `receiveNewVotes`, `active`)
|
||||
VALUE (?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$row->id_sondage_admin,
|
||||
$this->unescape($row->titre),
|
||||
$this->unescape($row->commentaires),
|
||||
$this->unescape($row->nom_admin),
|
||||
$this->unescape($row->mail_admin),
|
||||
$row->date_creation,
|
||||
$row->date_fin,
|
||||
$row->format,
|
||||
$row->editable,
|
||||
$row->mailsonde,
|
||||
$row->active
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createSlotTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('slot') . '` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`title` TEXT,
|
||||
`moments` TEXT,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8');
|
||||
}
|
||||
|
||||
private function migrateFromSujetStudsToSlot(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SELECT * FROM sujet_studs');
|
||||
$sujets = $stmt->fetchAll();
|
||||
$slots = [];
|
||||
|
||||
foreach ($sujets as $sujet) {
|
||||
$newSlots = $this->transformSujetToSlot($sujet);
|
||||
$slots = array_merge($slots, $newSlots);
|
||||
}
|
||||
|
||||
$prepared = $pdo->prepare('INSERT INTO ' . Utils::table('slot') . ' (`poll_id`, `title`, `moments`) VALUE (?,?,?)');
|
||||
foreach ($slots as $slot) {
|
||||
$prepared->execute([
|
||||
$slot->poll_id,
|
||||
$this->unescape($slot->title),
|
||||
!empty($slot->moments) ? $this->unescape($slot->moments) : null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createCommentTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('comment') . '` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`name` TEXT,
|
||||
`comment` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8');
|
||||
}
|
||||
|
||||
private function migrateFromCommentsToComment(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`usercomment`,
|
||||
`comment`
|
||||
FROM `comments`');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('comment') . '` (`poll_id`, `name`, `comment`)
|
||||
VALUE (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->usercomment),
|
||||
$this->unescape($row->comment)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createVoteTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('vote') . '` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`name` VARCHAR(64) NOT NULL,
|
||||
`choices` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8');
|
||||
}
|
||||
|
||||
private function migrateFromUserStudsToVote(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`nom`,
|
||||
REPLACE(REPLACE(REPLACE(`reponses`, 1, \'X\'), 2, 1), \'X\', 2) reponses
|
||||
FROM `user_studs`');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('vote') . '` (`poll_id`, `name`, `choices`)
|
||||
VALUE (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->nom),
|
||||
$row->reponses
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function transformSujetToSlot($sujet) {
|
||||
$slots = [];
|
||||
$ex = explode(',', $sujet->sujet);
|
||||
$isDatePoll = strpos($sujet->sujet, '@');
|
||||
$lastSlot = null;
|
||||
|
||||
foreach ($ex as $atomicSlot) {
|
||||
if ($isDatePoll === false) { // Classic poll
|
||||
$slot = new \stdClass();
|
||||
$slot->poll_id = $sujet->id_sondage;
|
||||
$slot->title = $atomicSlot;
|
||||
$slots[] = $slot;
|
||||
} else { // Date poll
|
||||
$values = explode('@', $atomicSlot);
|
||||
if ($lastSlot == null || $lastSlot->title !== $values[0]) {
|
||||
$lastSlot = new \stdClass();
|
||||
$lastSlot->poll_id = $sujet->id_sondage;
|
||||
$lastSlot->title = $values[0];
|
||||
$lastSlot->moments = count($values) == 2 ? $values[1] : '-';
|
||||
$slots[] = $lastSlot;
|
||||
} else {
|
||||
$lastSlot->moments .= ',' . (count($values) == 2 ? $values[1] : '-');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $slots;
|
||||
}
|
||||
|
||||
private function dropOldTables(\PDO $pdo) {
|
||||
$pdo->exec('DROP TABLE `comments`');
|
||||
$pdo->exec('DROP TABLE `sujet_studs`');
|
||||
$pdo->exec('DROP TABLE `user_studs`');
|
||||
$pdo->exec('DROP TABLE `sondage`');
|
||||
}
|
||||
|
||||
private function unescape($value) {
|
||||
return stripslashes(html_entity_decode($value, ENT_QUOTES));
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Framadate\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This class executes the aciton in database to migrate data from version 0.9 to 0.9.1.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
*/
|
||||
class From_0_9_to_0_9_1_Migration implements Migration {
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "From 0.9 to 0.9.1";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
ADD `receiveNewComments` TINYINT(1) DEFAULT \'0\'
|
||||
AFTER `receiveNewVotes`');
|
||||
}
|
||||
|
||||
}
|
31
app/classes/Framadate/Migration/Migration.php
Normal file
31
app/classes/Framadate/Migration/Migration.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Framadate\Migration;
|
||||
|
||||
interface Migration {
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description();
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the Migration should be executed
|
||||
*/
|
||||
function preCondition(\PDO $pdo);
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo);
|
||||
|
||||
}
|
||||
|
35
app/classes/Framadate/Security/Token.php
Normal file
35
app/classes/Framadate/Security/Token.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Framadate\Security;
|
||||
|
||||
class Token {
|
||||
|
||||
private $time;
|
||||
private $value;
|
||||
|
||||
function __construct() {
|
||||
$this->time = time() + TOKEN_TIME;
|
||||
$this->value = $this->generate();
|
||||
}
|
||||
|
||||
private function generate() {
|
||||
return sha1(uniqid(mt_rand(), true));
|
||||
}
|
||||
|
||||
public function getTime() {
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function isGone() {
|
||||
return $this->time < time();
|
||||
}
|
||||
|
||||
public function check($value) {
|
||||
return $value === $this->value;
|
||||
}
|
||||
|
||||
}
|
||||
|
270
app/classes/Framadate/Services/AdminPollService.php
Normal file
270
app/classes/Framadate/Services/AdminPollService.php
Normal file
@ -0,0 +1,270 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* Class AdminPollService
|
||||
*
|
||||
* @package Framadate\Services
|
||||
*/
|
||||
class AdminPollService {
|
||||
|
||||
private $connect;
|
||||
private $pollService;
|
||||
private $logService;
|
||||
|
||||
function __construct(FramaDB $connect, PollService $pollService, LogService $logService) {
|
||||
$this->connect = $connect;
|
||||
$this->pollService = $pollService;
|
||||
$this->logService = $logService;
|
||||
}
|
||||
|
||||
function updatePoll($poll) {
|
||||
global $config;
|
||||
if ($poll->end_date > $poll->creation_date && $poll->end_date <= strtotime($poll->creation_date) + (86400 * $config['default_poll_duration'])) {
|
||||
return $this->connect->updatePoll($poll);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a comment from a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $comment_id int The ID of the comment
|
||||
* @return mixed true is action succeeded
|
||||
*/
|
||||
function deleteComment($poll_id, $comment_id) {
|
||||
return $this->connect->deleteComment($poll_id, $comment_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all comments of a poll.
|
||||
*
|
||||
* @param $poll_id int The ID a the poll
|
||||
* @return bool|null true is action succeeded
|
||||
*/
|
||||
function cleanComments($poll_id) {
|
||||
$this->logService->log("CLEAN_COMMENTS", "id:$poll_id");
|
||||
return $this->connect->deleteCommentsByPollId($poll_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a vote from a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $vote_id int The ID of the vote
|
||||
* @return mixed true is action succeeded
|
||||
*/
|
||||
function deleteVote($poll_id, $vote_id) {
|
||||
return $this->connect->deleteVote($poll_id, $vote_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all votes of a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return bool|null true is action succeeded
|
||||
*/
|
||||
function cleanVotes($poll_id) {
|
||||
$this->logService->log('CLEAN_VOTES', 'id:' . $poll_id);
|
||||
return $this->connect->deleteVotesByPollId($poll_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the entire given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return bool true is action succeeded
|
||||
*/
|
||||
function deleteEntirePoll($poll_id) {
|
||||
$poll = $this->connect->findPollById($poll_id);
|
||||
$this->logService->log('DELETE_POLL', "id:$poll->id, format:$poll->format, admin:$poll->admin_name, mail:$poll->admin_mail");
|
||||
|
||||
// Delete the entire poll
|
||||
$this->connect->deleteVotesByPollId($poll_id);
|
||||
$this->connect->deleteCommentsByPollId($poll_id);
|
||||
$this->connect->deleteSlotsByPollId($poll_id);
|
||||
$this->connect->deletePollById($poll_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a slot from a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $slot object The slot informations (datetime + moment)
|
||||
* @return bool true if action succeeded
|
||||
*/
|
||||
public function deleteDateSlot($poll_id, $slot) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . json_encode($slot));
|
||||
|
||||
$datetime = $slot->title;
|
||||
$moment = $slot->moment;
|
||||
|
||||
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
||||
|
||||
$index = 0;
|
||||
$indexToDelete = -1;
|
||||
$newMoments = [];
|
||||
|
||||
// Search the index of the slot to delete
|
||||
foreach ($slots as $aSlot) {
|
||||
$moments = explode(',', $aSlot->moments);
|
||||
|
||||
foreach ($moments as $rowMoment) {
|
||||
if ($datetime == $aSlot->title) {
|
||||
if ($moment == $rowMoment) {
|
||||
$indexToDelete = $index;
|
||||
} else {
|
||||
$newMoments[] = $rowMoment;
|
||||
}
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove votes
|
||||
$this->connect->beginTransaction();
|
||||
$this->connect->deleteVotesByIndex($poll_id, $indexToDelete);
|
||||
if (count($newMoments) > 0) {
|
||||
$this->connect->updateSlot($poll_id, $datetime, implode(',', $newMoments));
|
||||
} else {
|
||||
$this->connect->deleteSlot($poll_id, $datetime);
|
||||
}
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteClassicSlot($poll_id, $slot_title) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . $slot_title);
|
||||
|
||||
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
||||
|
||||
$index = 0;
|
||||
$indexToDelete = -1;
|
||||
|
||||
// Search the index of the slot to delete
|
||||
foreach ($slots as $aSlot) {
|
||||
if ($slot_title == $aSlot->title) {
|
||||
$indexToDelete = $index;
|
||||
}
|
||||
$index++;
|
||||
}
|
||||
|
||||
// Remove votes
|
||||
$this->connect->beginTransaction();
|
||||
$this->connect->deleteVotesByIndex($poll_id, $indexToDelete);
|
||||
$this->connect->deleteSlot($poll_id, $slot_title);
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new slot to the poll. And insert default values for user's votes.
|
||||
* <ul>
|
||||
* <li>Create a new slot if no one exists for the given date</li>
|
||||
* <li>Create a new moment if a slot already exists for the given date</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime int The datetime
|
||||
* @param $new_moment string The moment's name
|
||||
* @return bool true if added
|
||||
*/
|
||||
public function addSlot($poll_id, $datetime, $new_moment) {
|
||||
$slots = $this->connect->allSlotsByPollId($poll_id);
|
||||
$result = $this->findInsertPosition($slots, $datetime, $new_moment);
|
||||
|
||||
// Begin transaction
|
||||
$this->connect->beginTransaction();
|
||||
|
||||
if ($result == null) {
|
||||
// The moment already exists
|
||||
return false;
|
||||
} elseif ($result->slot != null) {
|
||||
$slot = $result->slot;
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
// Check if moment already exists (maybe not necessary)
|
||||
if (in_array($new_moment, $moments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update found slot
|
||||
$moments[] = $new_moment;
|
||||
sort($moments);
|
||||
$this->connect->updateSlot($poll_id, $datetime, implode(',', $moments));
|
||||
|
||||
} else {
|
||||
$this->connect->insertSlot($poll_id, $datetime, $new_moment);
|
||||
}
|
||||
|
||||
$this->connect->insertDefaultVote($poll_id, $result->insert);
|
||||
|
||||
// Commit transaction
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method find where to insert a datatime+moment into a list of slots.<br/>
|
||||
* Return the {insert:X}, where X is the index of the moment into the whole poll (ex: X=0 => Insert to the first column).
|
||||
* Return {slot:Y}, where Y is not null if there is a slot existing for the given datetime.
|
||||
*
|
||||
* @param $slots array All the slots of the poll
|
||||
* @param $datetime int The datetime of the new slot
|
||||
* @param $moment string The moment's name
|
||||
* @return null|\stdClass An object like this one: {insert:X, slot:Y} where Y can be null.
|
||||
*/
|
||||
private function findInsertPosition($slots, $datetime, $moment) {
|
||||
$result = new \stdClass();
|
||||
$result->slot = null;
|
||||
$result->insert = -1;
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ($slots as $slot) {
|
||||
$rowDatetime = $slot->title;
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
if ($datetime == $rowDatetime) {
|
||||
$result->slot = $slot;
|
||||
|
||||
foreach ($moments as $rowMoment) {
|
||||
$strcmp = strcmp($moment, $rowMoment);
|
||||
if ($strcmp < 0) {
|
||||
// Here we have to insert at First place or middle of the slot
|
||||
break(2);
|
||||
} elseif ($strcmp == 0) {
|
||||
// Here we dont have to insert at all
|
||||
return null;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Here we have to insert at the end of a slot
|
||||
$result->insert = $i;
|
||||
break;
|
||||
} elseif ($datetime < $rowDatetime) {
|
||||
// Here we have to insert a new slot
|
||||
break;
|
||||
} else {
|
||||
$i += count($moments);
|
||||
}
|
||||
}
|
||||
$result->insert = $i;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
49
app/classes/Framadate/Services/InputService.php
Normal file
49
app/classes/Framadate/Services/InputService.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate\Services;
|
||||
|
||||
/**
|
||||
* This class helps to clean all inputs from the users or external services.
|
||||
*/
|
||||
class InputService {
|
||||
|
||||
function __construct() {}
|
||||
|
||||
/**
|
||||
* This method filter an array calling "filter_var" on each items.
|
||||
* Only items validated are added at their own indexes, the others are not returned.
|
||||
*/
|
||||
function filterArray(array $arr, $type, $options = null) {
|
||||
$newArr = [];
|
||||
|
||||
foreach($arr as $id=>$item) {
|
||||
$item = filter_var($item, $type, $options);
|
||||
if ($item !== false) {
|
||||
$newArr[$id] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $newArr;
|
||||
}
|
||||
|
||||
function filterAllowedValues($value, array $allowedValues) {
|
||||
return in_array($value, $allowedValues, true) ? $value : null;
|
||||
}
|
||||
|
||||
}
|
25
app/classes/Framadate/Services/LogService.php
Normal file
25
app/classes/Framadate/Services/LogService.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
/**
|
||||
* This service provides a standard way to log some informations.
|
||||
*
|
||||
* @package Framadate\Services
|
||||
*/
|
||||
class LogService {
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message to the log file.
|
||||
*
|
||||
* @param $tag string A tag is used to quickly found a message when reading log file
|
||||
* @param $message string some message
|
||||
*/
|
||||
function log($tag, $message) {
|
||||
error_log(date('Ymd His') . ' [' . $tag . '] ' . $message . "\n", 3, ROOT_DIR . LOG_FILE);
|
||||
}
|
||||
|
||||
}
|
||||
|
49
app/classes/Framadate/Services/MailService.php
Normal file
49
app/classes/Framadate/Services/MailService.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
class MailService {
|
||||
|
||||
private $smtp_allowed;
|
||||
|
||||
function __construct($smtp_allowed) {
|
||||
$this->smtp_allowed = $smtp_allowed;
|
||||
}
|
||||
|
||||
public function isValidEmail($email) {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
function send($to, $subject, $body, $param = '') {
|
||||
if($this->smtp_allowed == true) {
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
$subject = mb_encode_mimeheader(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'), 'UTF-8', 'B', "\n", 9);
|
||||
|
||||
$encoded_app = mb_encode_mimeheader(NOMAPPLICATION, 'UTF-8', 'B', "\n", 6);
|
||||
$size_encoded_app = (6 + strlen($encoded_app)) % 75;
|
||||
$size_admin_email = strlen(ADRESSEMAILADMIN);
|
||||
|
||||
if (($size_encoded_app + $size_admin_email + 9) > 74) {
|
||||
$folding = "\n";
|
||||
} else {
|
||||
$folding = '';
|
||||
};
|
||||
|
||||
$from = sprintf("From: %s%s <%s>\n", $encoded_app, $folding, ADRESSEMAILADMIN);
|
||||
|
||||
$headers = $from;
|
||||
$headers .= 'Reply-To: ' . ADRESSEMAILREPONSEAUTO . "\n";
|
||||
$headers .= "MIME-Version: 1.0\n";
|
||||
$headers .= "Content-Type: text/plain; charset=UTF-8\n";
|
||||
$headers .= "Content-Transfer-Encoding: 8bit\n";
|
||||
$headers .= "Auto-Submitted:auto-generated\n";
|
||||
$headers .= 'Return-Path: <>';
|
||||
|
||||
$body = html_entity_decode($body, ENT_QUOTES, 'UTF-8') . _("\n--\n\n« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org.");
|
||||
|
||||
mail($to, $subject, $body, $headers, $param);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
190
app/classes/Framadate/Services/PollService.php
Normal file
190
app/classes/Framadate/Services/PollService.php
Normal file
@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\Form;
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Utils;
|
||||
|
||||
class PollService {
|
||||
|
||||
private $connect;
|
||||
private $logService;
|
||||
|
||||
function __construct(FramaDB $connect, LogService $logService) {
|
||||
$this->connect = $connect;
|
||||
$this->logService = $logService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a poll from its ID.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return \stdClass|null The found poll, or null
|
||||
*/
|
||||
function findById($poll_id) {
|
||||
if (preg_match('/^[\w\d]{16}$/i', $poll_id)) {
|
||||
return $this->connect->findPollById($poll_id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function allCommentsByPollId($poll_id) {
|
||||
return $this->connect->allCommentsByPollId($poll_id);
|
||||
}
|
||||
|
||||
function allVotesByPollId($poll_id) {
|
||||
return $this->connect->allUserVotesByPollId($poll_id);
|
||||
}
|
||||
|
||||
function allSlotsByPollId($poll_id) {
|
||||
return $this->connect->allSlotsByPollId($poll_id);
|
||||
}
|
||||
|
||||
public function updateVote($poll_id, $vote_id, $name, $choices) {
|
||||
$choices = implode($choices);
|
||||
|
||||
return $this->connect->updateVote($poll_id, $vote_id, $name, $choices);
|
||||
}
|
||||
|
||||
function addVote($poll_id, $name, $choices) {
|
||||
$choices = implode($choices);
|
||||
|
||||
return $this->connect->insertVote($poll_id, $name, $choices);
|
||||
}
|
||||
|
||||
function addComment($poll_id, $name, $comment) {
|
||||
// TODO Check if there is no duplicate before to add a new comment
|
||||
return $this->connect->insertComment($poll_id, $name, $comment);
|
||||
}
|
||||
|
||||
public function countVotesByPollId($poll_id) {
|
||||
return $this->connect->countVotesByPollId($poll_id);
|
||||
}
|
||||
|
||||
function computeBestChoices($votes) {
|
||||
$result = [];
|
||||
foreach ($votes as $vote) {
|
||||
$choices = str_split($vote->choices);
|
||||
foreach ($choices as $i => $choice) {
|
||||
if (empty($result[$i])) {
|
||||
$result[$i] = 0;
|
||||
}
|
||||
if ($choice == 2) {
|
||||
$result[$i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function splitSlots($slots) {
|
||||
$splitted = array();
|
||||
foreach ($slots as $slot) {
|
||||
$obj = new \stdClass();
|
||||
$obj->day = $slot->title;
|
||||
$obj->moments = explode(',', $slot->moments);
|
||||
|
||||
$splitted[] = $obj;
|
||||
}
|
||||
|
||||
return $splitted;
|
||||
}
|
||||
|
||||
function splitVotes($votes) {
|
||||
$splitted = array();
|
||||
foreach ($votes as $vote) {
|
||||
$obj = new \stdClass();
|
||||
$obj->id = $vote->id;
|
||||
$obj->name = $vote->name;
|
||||
$obj->choices = str_split($vote->choices);
|
||||
|
||||
$splitted[] = $obj;
|
||||
}
|
||||
|
||||
return $splitted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Form $form
|
||||
* @return string
|
||||
*/
|
||||
function createPoll(Form $form) {
|
||||
|
||||
// Generate poll IDs
|
||||
$poll_id = $this->random(16);
|
||||
$admin_poll_id = $poll_id . $this->random(8);
|
||||
|
||||
// Insert poll + slots
|
||||
$this->connect->beginTransaction();
|
||||
|
||||
// TODO Extract this to FramaDB (or repository layer)
|
||||
$sql = 'INSERT INTO ' . Utils::table('poll') . '
|
||||
(id, admin_id, title, description, admin_name, admin_mail, end_date, format, editable, receiveNewVotes, receiveNewComments)
|
||||
VALUES (?,?,?,?,?,?,FROM_UNIXTIME(?),?,?,?,?)';
|
||||
$prepared = $this->connect->prepare($sql);
|
||||
$prepared->execute(array($poll_id, $admin_poll_id, $form->title, $form->description, $form->admin_name, $form->admin_mail, $form->end_date, $form->format, $form->editable, $form->receiveNewVotes, $form->receiveNewComments));
|
||||
|
||||
$prepared = $this->connect->prepare('INSERT INTO ' . Utils::table('slot') . ' (poll_id, title, moments) VALUES (?, ?, ?)');
|
||||
|
||||
foreach ($form->getChoices() as $choice) {
|
||||
|
||||
// We prepared the slots (joined by comas)
|
||||
$joinedSlots = '';
|
||||
$first = true;
|
||||
foreach ($choice->getSlots() as $slot) {
|
||||
if ($first) {
|
||||
$joinedSlots = $slot;
|
||||
$first = false;
|
||||
} else {
|
||||
$joinedSlots .= ',' . $slot;
|
||||
}
|
||||
}
|
||||
|
||||
// We execute the insertion
|
||||
if (empty($joinedSlots)) {
|
||||
$prepared->execute(array($poll_id, $choice->getName(), null));
|
||||
} else {
|
||||
$prepared->execute(array($poll_id, $choice->getName(), $joinedSlots));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->connect->commit();
|
||||
|
||||
$this->logService->log('CREATE_POLL', 'id:' . $poll_id . ', title: ' . $form->title . ', format:' . $form->format . ', admin:' . $form->admin_name . ', mail:' . $form->admin_mail);
|
||||
|
||||
|
||||
return [$poll_id, $admin_poll_id];
|
||||
}
|
||||
|
||||
private function random($car) {
|
||||
// TODO Better random ?
|
||||
$string = '';
|
||||
$chaine = 'abcdefghijklmnopqrstuvwxyz123456789';
|
||||
mt_srand();
|
||||
for ($i = 0; $i < $car; $i++) {
|
||||
$string .= $chaine[mt_rand() % strlen($chaine)];
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
69
app/classes/Framadate/Services/PurgeService.php
Normal file
69
app/classes/Framadate/Services/PurgeService.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
use Framadate\FramaDB;
|
||||
|
||||
/**
|
||||
* This service helps to purge data.
|
||||
*
|
||||
* @package Framadate\Services
|
||||
*/
|
||||
class PurgeService {
|
||||
|
||||
private $connect;
|
||||
private $logService;
|
||||
|
||||
function __construct(FramaDB $connect, LogService $logService) {
|
||||
$this->connect = $connect;
|
||||
$this->logService = $logService;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode purges all old polls (the ones with end_date in past).
|
||||
*
|
||||
* @return bool true is action succeeded
|
||||
*/
|
||||
function purgeOldPolls() {
|
||||
$oldPolls = $this->connect->findOldPolls();
|
||||
$count = count($oldPolls);
|
||||
|
||||
if ($count > 0) {
|
||||
$this->logService->log('EXPIRATION', 'Going to purge ' . $count . ' poll(s)...');
|
||||
|
||||
foreach ($oldPolls as $poll) {
|
||||
if ($this->purgePollById($poll->id)) {
|
||||
$this->logService->log('EXPIRATION_SUCCESS', 'id: ' . $poll->id . ', title:' . $poll->title . ', format: '.$poll->format . ', admin: ' . $poll->admin_name);
|
||||
} else {
|
||||
$this->logService->log('EXPIRATION_FAILED', 'id: ' . $poll->id . ', title:' . $poll->title . ', format: '.$poll->format . ', admin: ' . $poll->admin_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode delete all data about a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return bool true is action succeeded
|
||||
*/
|
||||
function purgePollById($poll_id) {
|
||||
$done = true;
|
||||
|
||||
$this->connect->beginTransaction();
|
||||
$done &= $this->connect->deleteCommentsByPollId($poll_id);
|
||||
$done &= $this->connect->deleteVotesByPollId($poll_id);
|
||||
$done &= $this->connect->deleteSlotsByPollId($poll_id);
|
||||
$done &= $this->connect->deletePollById($poll_id);
|
||||
|
||||
if ($done) {
|
||||
$this->connect->commit();
|
||||
} else {
|
||||
$this->connect->rollback();
|
||||
}
|
||||
|
||||
return $done;
|
||||
}
|
||||
|
||||
}
|
||||
|
52
app/classes/Framadate/Services/SecurityService.php
Normal file
52
app/classes/Framadate/Services/SecurityService.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\Security\Token;
|
||||
|
||||
class SecurityService {
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a CSRF token by name, or (re)create it.
|
||||
*
|
||||
* It creates a new token if :
|
||||
* <ul>
|
||||
* <li>There no token with the given name in session</li>
|
||||
* <li>The token time is in past</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param $tokan_name string The name of the CSRF token
|
||||
* @return Token The token
|
||||
*/
|
||||
function getToken($tokan_name) {
|
||||
if (!isset($_SESSION['tokens'])) {
|
||||
$_SESSION['tokens'] = [];
|
||||
}
|
||||
if (!isset($_SESSION['tokens'][$tokan_name]) || $_SESSION['tokens'][$tokan_name]->isGone()) {
|
||||
$_SESSION['tokens'][$tokan_name] = new Token();
|
||||
}
|
||||
|
||||
return $_SESSION['tokens'][$tokan_name]->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is corresponding to the token in session.
|
||||
*
|
||||
* @param $tokan_name string Name of the token
|
||||
* @param $csrf string Value to check
|
||||
* @return bool true if the token is well checked
|
||||
*/
|
||||
public function checkCsrf($tokan_name, $csrf) {
|
||||
$checked = $_SESSION['tokens'][$tokan_name]->getValue() === $csrf;
|
||||
|
||||
if($checked) {
|
||||
unset($_SESSION['tokens'][$tokan_name]);
|
||||
}
|
||||
|
||||
return $checked;
|
||||
}
|
||||
|
||||
}
|
||||
|
32
app/classes/Framadate/Services/SuperAdminService.php
Normal file
32
app/classes/Framadate/Services/SuperAdminService.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
|
||||
/**
|
||||
* The class provides action for application administrators.
|
||||
*
|
||||
* @package Framadate\Services
|
||||
*/
|
||||
class SuperAdminService {
|
||||
|
||||
private $connect;
|
||||
|
||||
function __construct(FramaDB $connect) {
|
||||
$this->connect = $connect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of all polls.
|
||||
*
|
||||
* @param $page int The page index (O = first page)
|
||||
* @param $limit int The limit size
|
||||
* @return array ['polls' => The {$limit} polls, 'count' => Total count]
|
||||
* polls, 'count' => Total count]
|
||||
*/
|
||||
public function findAllPolls($page, $limit) {
|
||||
return $this->connect->findAllPolls($page * $limit, $limit);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,45 +18,21 @@
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
class Utils
|
||||
{
|
||||
public static function get_server_name()
|
||||
{
|
||||
$scheme = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http';
|
||||
$port = in_array($_SERVER['SERVER_PORT'], [80, 443]) ? '/' : ':' . $_SERVER['SERVER_PORT'] . '/';
|
||||
$server_name = $_SERVER['SERVER_NAME'] . $port . dirname($_SERVER['SCRIPT_NAME']) . '/';
|
||||
class Utils {
|
||||
/**
|
||||
* @return string Server name
|
||||
*/
|
||||
public static function get_server_name() {
|
||||
$scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
|
||||
$port = in_array($_SERVER['SERVER_PORT'], [80, 443]) ? '' : ':' . $_SERVER['SERVER_PORT'];
|
||||
$dirname = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$dirname = $dirname === '\\' ? '/' : $dirname . '/';
|
||||
$server_name = $_SERVER['SERVER_NAME'] . $port . $dirname;
|
||||
|
||||
return $scheme . '://' . str_replace('/admin','',str_replace('//','/',str_replace('///','/',$server_name)));
|
||||
return $scheme . '://' . str_replace('/admin', '', str_replace('//', '/', str_replace('///', '/', $server_name)));
|
||||
}
|
||||
|
||||
public static function get_sondage_from_id($id)
|
||||
{
|
||||
global $connect;
|
||||
|
||||
// Open database
|
||||
if (preg_match(';^[\w\d]{16}$;i', $id)) {
|
||||
$sql = 'SELECT sondage.*,sujet_studs.sujet FROM sondage
|
||||
LEFT OUTER JOIN sujet_studs ON sondage.id_sondage = sujet_studs.id_sondage
|
||||
WHERE sondage.id_sondage = ' . $connect->Param('id_sondage');
|
||||
|
||||
$sql = $connect->Prepare($sql);
|
||||
$sondage = $connect->Execute($sql, [$id]);
|
||||
|
||||
if ($sondage === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$psondage = $sondage->FetchObject(false);
|
||||
$psondage->date_fin = strtotime($psondage->date_fin);
|
||||
|
||||
return $psondage;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function is_error($cerr)
|
||||
{
|
||||
public static function is_error($cerr) {
|
||||
global $err;
|
||||
if ($err == 0) {
|
||||
return false;
|
||||
@ -65,38 +41,40 @@ class Utils
|
||||
return ($err & $cerr) != 0;
|
||||
}
|
||||
|
||||
public static function is_user()
|
||||
{
|
||||
public static function is_user() {
|
||||
return (USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) || isset($_SESSION['nom']);
|
||||
}
|
||||
|
||||
public static function print_header($title = '')
|
||||
{
|
||||
global $lang;
|
||||
/**
|
||||
* @param string $title
|
||||
* @deprecated
|
||||
*/
|
||||
public static function print_header($title = '') {
|
||||
global $html_lang;
|
||||
|
||||
echo '<!DOCTYPE html>
|
||||
<html lang="'.$lang.'">
|
||||
<html lang="' . $html_lang . '">
|
||||
<head>
|
||||
<meta charset="utf-8">';
|
||||
<meta charset="utf-8" />';
|
||||
|
||||
if (! empty($title)) {
|
||||
if (!empty($title)) {
|
||||
echo '<title>' . stripslashes($title) . ' - ' . NOMAPPLICATION . '</title>';
|
||||
} else {
|
||||
echo '<title>' . NOMAPPLICATION . '</title>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/datepicker3.css">
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/style.css">
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/frama.css">
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/print.css" media="print">
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/datepicker3.css" />
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/style.css" />
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/frama.css" />
|
||||
<link rel="stylesheet" href="' . self::get_server_name() . 'css/print.css" media="print" />
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/jquery-1.11.1.min.js"></script>
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/bootstrap-datepicker.js"></script>
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/locales/bootstrap-datepicker.'.$lang.'.js"></script>
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/locales/bootstrap-datepicker.' . $html_lang . '.js"></script>
|
||||
<script type="text/javascript" src="' . self::get_server_name() . 'js/core.js"></script>';
|
||||
if (file_exists($_SERVER['DOCUMENT_ROOT']."/nav/nav.js")) {
|
||||
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/nav/nav.js")) {
|
||||
echo '<script src="/nav/nav.js" id="nav_js" type="text/javascript" charset="utf-8"></script><!-- /Framanav -->';
|
||||
}
|
||||
|
||||
@ -104,107 +82,26 @@ class Utils
|
||||
</head>
|
||||
<body>
|
||||
<div class="container ombre">';
|
||||
|
||||
}
|
||||
|
||||
public static function check_table_sondage()
|
||||
{
|
||||
global $connect;
|
||||
|
||||
if (in_array('sondage', $connect->MetaTables('TABLES'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an email address is valid using PHP filters
|
||||
*
|
||||
* @param string $email Email address to check
|
||||
* @param string $email Email address to check
|
||||
* @return bool True if valid. False if not valid.
|
||||
* @deprecated
|
||||
*/
|
||||
public static function isValidEmail($email)
|
||||
{
|
||||
public static function isValidEmail($email) {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Envoi un courrier avec un codage correct de To et Subject
|
||||
* Les en-têtes complémentaires ne sont pas gérés
|
||||
*
|
||||
*/
|
||||
public static function sendEmail( $to, $subject, $body, $headers='', $param='')
|
||||
{
|
||||
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
$subject = mb_encode_mimeheader(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'), 'UTF-8', 'B', "\n", 9);
|
||||
|
||||
$encoded_app = mb_encode_mimeheader(NOMAPPLICATION, 'UTF-8', 'B', "\n", 6);
|
||||
$size_encoded_app = (6 + strlen($encoded_app)) % 75;
|
||||
$size_admin_email = strlen(ADRESSEMAILADMIN);
|
||||
|
||||
if (($size_encoded_app + $size_admin_email + 9) > 74 ) {
|
||||
$folding = "\n";
|
||||
} else {
|
||||
$folding = '';
|
||||
};
|
||||
|
||||
/*
|
||||
Si $headers ne contient qu'une adresse email, on la considère comme
|
||||
adresse de reply-to, sinon on met l'adresse de no-reply definie
|
||||
dans constants.php
|
||||
*/
|
||||
if (self::isValidEmail($headers)) {
|
||||
$replyTo = $headers;
|
||||
$headers = ''; // on reinitialise $headers
|
||||
} else {
|
||||
$replyTo = ADRESSEMAILREPONSEAUTO;
|
||||
}
|
||||
|
||||
$from = sprintf( "From: %s%s <%s>\n", $encoded_app, $folding, ADRESSEMAILADMIN);
|
||||
|
||||
if ($headers) {
|
||||
$headers .= "\n" ;
|
||||
}
|
||||
|
||||
$headers .= $from;
|
||||
$headers .= "Reply-To: $replyTo\n";
|
||||
$headers .= "MIME-Version: 1.0\n";
|
||||
$headers .= "Content-Type: text/plain; charset=UTF-8\n";
|
||||
$headers .= "Content-Transfer-Encoding: 8bit\n";
|
||||
$headers .= "Auto-Submitted:auto-generated\n";
|
||||
$headers .= "Return-Path: <>";
|
||||
|
||||
$body = html_entity_decode($body, ENT_QUOTES, 'UTF-8')._("\n--\n\n« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org.");
|
||||
|
||||
mail($to, $subject, $body, $headers, $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction vérifiant l'existance et la valeur non vide d'une clé d'un tableau
|
||||
* @param string $name La clé à tester
|
||||
* @param array $tableau Le tableau où rechercher la clé ($_POST par défaut)
|
||||
* @return bool Vrai si la clé existe et renvoie une valeur non vide
|
||||
*/
|
||||
public static function issetAndNoEmpty($name, $tableau = null)
|
||||
{
|
||||
if (is_null($tableau)) {
|
||||
$tableau = $_POST;
|
||||
}
|
||||
|
||||
return isset($tableau[$name]) && ! empty($tableau[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction permettant de générer les URL pour les sondage
|
||||
* @param string $id L'identifiant du sondage
|
||||
* @param bool $admin True pour générer une URL pour l'administration d'un sondage, False pour un URL publique
|
||||
* @param string $id L'identifiant du sondage
|
||||
* @param bool $admin True pour générer une URL pour l'administration d'un sondage, False pour un URL publique
|
||||
* @return string L'url pour le sondage
|
||||
*/
|
||||
public static function getUrlSondage($id, $admin = false)
|
||||
{
|
||||
public static function getUrlSondage($id, $admin = false) {
|
||||
if (URL_PROPRE) {
|
||||
if ($admin === true) {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . $id . '/admin';
|
||||
@ -213,52 +110,75 @@ class Utils
|
||||
}
|
||||
} else {
|
||||
if ($admin === true) {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'adminstuds.php?sondage=' . $id;
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'adminstuds.php?poll=' . $id;
|
||||
} else {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'studs.php?sondage=' . $id;
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'studs.php?poll=' . $id;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function remove_sondage($connect, $numsondage)
|
||||
{
|
||||
$connect->StartTrans();
|
||||
|
||||
$req = 'DELETE FROM sondage WHERE id_sondage = ' . $connect->Param('numsondage') ;
|
||||
$sql = $connect->Prepare($req);
|
||||
$connect->Execute($sql, [$numsondage]);
|
||||
|
||||
$req = 'DELETE FROM sujet_studs WHERE id_sondage = ' . $connect->Param('numsondage') ;
|
||||
$sql = $connect->Prepare($req);
|
||||
$connect->Execute($sql, [$numsondage]);
|
||||
|
||||
$req = 'DELETE FROM user_studs WHERE id_sondage = ' . $connect->Param('numsondage') ;
|
||||
$sql = $connect->Prepare($req);
|
||||
$connect->Execute($sql, [$numsondage]);
|
||||
|
||||
$req = 'DELETE FROM comments WHERE id_sondage = ' . $connect->Param('numsondage') ;
|
||||
$sql = $connect->Prepare($req);
|
||||
$connect->Execute($sql, [$numsondage]);
|
||||
|
||||
$suppression_OK = ! $connect->HasFailedTrans();
|
||||
$connect->CompleteTrans();
|
||||
|
||||
return $suppression_OK ;
|
||||
/**
|
||||
* This method pretty prints an object to the page framed by pre tags.
|
||||
*
|
||||
* @param mixed $object The object to print.
|
||||
*/
|
||||
public static function debug($object) {
|
||||
echo '<pre>';
|
||||
print_r($object);
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
public static function cleaning_polls($connect, $log_txt) {
|
||||
$connect->StartTrans();
|
||||
$req = 'SELECT * FROM sondage WHERE date_fin < NOW() AND date_fin != 0 LIMIT 20';
|
||||
$sql = $connect->Prepare($req);
|
||||
$cleaning = $connect->Execute($sql);
|
||||
public static function table($tableName) {
|
||||
return TABLENAME_PREFIX . $tableName;
|
||||
}
|
||||
|
||||
public static function markdown($md, $clear) {
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/', $md, $md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/', $md, $md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/', $md, $md_a); // Markdown [text](href)
|
||||
if (isset($md_a_img[2][0]) && $md_a_img[2][0] != '' && isset($md_a_img[3][0]) && $md_a_img[3][0] != '') { // [![alt](src)](href)
|
||||
|
||||
$text = stripslashes($md_a_img[1][0]);
|
||||
$html = '<a href="' . $md_a_img[3][0] . '"><img src="' . $md_a_img[2][0] . '" class="img-responsive" alt="' . $text . '" title="' . $text . '" /></a>';
|
||||
|
||||
} elseif (isset($md_img[2][0]) && $md_img[2][0] != '') { // ![alt](src)
|
||||
|
||||
$text = stripslashes($md_img[1][0]);
|
||||
$html = '<img src="' . $md_img[2][0] . '" class="img-responsive" alt="' . $text . '" title="' . $text . '" />';
|
||||
|
||||
} elseif (isset($md_a[2][0]) && $md_a[2][0] != '') { // [text](href)
|
||||
|
||||
$text = stripslashes($md_a[1][0]);
|
||||
$html = '<a href="' . $md_a[2][0] . '">' . $text . '</a>';
|
||||
|
||||
} else { // text only
|
||||
|
||||
$text = stripslashes($md);
|
||||
$html = $text;
|
||||
|
||||
while ($dcleaning = $cleaning->FetchNextObject(false)) {
|
||||
if (self::remove_sondage($connect, $dcleaning->id_sondage)) {
|
||||
error_log(date('H:i:s d/m/Y:') . ' EXPIRATION: '. $dcleaning->id_sondage."\t".$dcleaning->format."\t".$dcleaning->nom_admin."\t".$dcleaning->mail_admin."\n", 3, $log_txt);
|
||||
}
|
||||
}
|
||||
$connect->CompleteTrans();
|
||||
|
||||
return $clear ? $text : $html;
|
||||
}
|
||||
|
||||
public static function htmlEscape($html) {
|
||||
return htmlentities($html, ENT_HTML5 | ENT_QUOTES);
|
||||
}
|
||||
|
||||
public static function csvEscape($text) {
|
||||
$escaped = str_replace('"', '""', $text);
|
||||
$escaped = str_replace("\r\n", '', $escaped);
|
||||
$escaped = str_replace("\n", '', $escaped);
|
||||
|
||||
return '"' . $escaped . '"';
|
||||
}
|
||||
|
||||
public static function cleanFilename($title) {
|
||||
$cleaned = preg_replace('[^a-zA-Z0-9._-]', '_', $title);
|
||||
$cleaned = preg_replace(' {2,}', ' ', $cleaned);
|
||||
|
||||
return $cleaned;
|
||||
}
|
||||
}
|
||||
|
@ -17,14 +17,8 @@
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
// FRAMADATE version
|
||||
const VERSION = 0.8;
|
||||
|
||||
// Server name
|
||||
const STUDS_URL = '<www.mydomain.com>';
|
||||
|
||||
// Application name
|
||||
const NOMAPPLICATION = "<Application name>";
|
||||
const NOMAPPLICATION = '<Application name>';
|
||||
|
||||
// Database administrator email
|
||||
const ADRESSEMAILADMIN = '<email address>';
|
||||
@ -32,20 +26,20 @@ const ADRESSEMAILADMIN = '<email address>';
|
||||
// Email for automatic responses (you should set it to "no-reply")
|
||||
const ADRESSEMAILREPONSEAUTO = '<no-reply@mydomain.com>';
|
||||
|
||||
// Database name
|
||||
const BASE = '<database name>';
|
||||
|
||||
// Database user
|
||||
const USERBASE = "<database user>";
|
||||
const DB_USER= '<database user>';
|
||||
|
||||
// Database password
|
||||
const USERPASSWD = '<database password>';
|
||||
const DB_PASSWORD = '<database password>';
|
||||
|
||||
// Database server name, leave empty to use a socket
|
||||
const SERVEURBASE = '<database server>';
|
||||
const DB_CONNECTION_STRING = 'mysql:host=<database host>;dbname=<database name>;port=<database port>';
|
||||
|
||||
// Database type (mysql, postgres…) http://phplens.com/lens/adodb/docs-adodb.htm#drivers
|
||||
const BASE_TYPE = '<database type>';
|
||||
// Name of the table that store migration script already executed
|
||||
const MIGRATION_TABLE = 'framadate_migration';
|
||||
|
||||
// Table name prefix
|
||||
const TABLENAME_PREFIX = 'fd_';
|
||||
|
||||
// Default Language using POSIX variant of BC P47 standard (choose in $ALLOWED_LANGUAGES)
|
||||
const LANGUE = 'fr_FR';
|
||||
@ -73,16 +67,11 @@ const URL_PROPRE = false;
|
||||
// Use REMOTE_USER data provided by web server
|
||||
const USE_REMOTE_USER = true;
|
||||
|
||||
const COMMENT_EMPTY = 0x0000000001;
|
||||
const COMMENT_USER_EMPTY = 0x0000000010;
|
||||
const COMMENT_INSERT_FAILED = 0x0000000100;
|
||||
const NAME_EMPTY = 0x0000001000;
|
||||
const NAME_TAKEN = 0x0000010000;
|
||||
const NO_POLL = 0x0000100000;
|
||||
const NO_POLL_ID = 0x0001000000;
|
||||
const INVALID_EMAIL = 0x0010000000;
|
||||
const TITLE_EMPTY = 0x0100000000;
|
||||
const INVALID_DATE = 0x1000000000;
|
||||
// Path to the log file
|
||||
const LOG_FILE = 'admin/stdout.log';
|
||||
|
||||
// Days (after expiration date) before purge a poll
|
||||
const PURGE_DELAY = 60;
|
||||
|
||||
// Config
|
||||
$config = [
|
||||
@ -93,8 +82,8 @@ $config = [
|
||||
'show_the_software' => true, // display technical information about the software
|
||||
'show_cultivate_your_garden' => true, // display "developpement and administration" information
|
||||
/* choix_autre.php / choix_date.php */
|
||||
'default_poll_duration' => 180, // default values for the new poll duration (number of days).
|
||||
'default_poll_duration' => 180, // default values for the new poll duration (number of days).
|
||||
/* choix_autre.php */
|
||||
'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll.
|
||||
'user_can_add_img_or_link' => true, // user can add link or URL when creating his poll.
|
||||
];
|
||||
|
42
app/inc/constants.php
Normal file
42
app/inc/constants.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
// FRAMADATE version
|
||||
const VERSION = '0.9.1';
|
||||
|
||||
// Regex
|
||||
const POLL_REGEX = '/^[a-z0-9]+$/';
|
||||
const CHOICE_REGEX = '/^[012]$/';
|
||||
const NAME_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9_ -]+$/i';
|
||||
const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/';
|
||||
|
||||
// CSRF (300s = 5min)
|
||||
const TOKEN_TIME = 300;
|
||||
|
||||
// Errors
|
||||
const COMMENT_EMPTY = 0x0000000001;
|
||||
const COMMENT_USER_EMPTY = 0x0000000010;
|
||||
const COMMENT_INSERT_FAILED = 0x0000000100;
|
||||
const NAME_EMPTY = 0x0000001000;
|
||||
const NAME_TAKEN = 0x0000010000;
|
||||
const NO_POLL = 0x0000100000;
|
||||
const NO_POLL_ID = 0x0001000000;
|
||||
const INVALID_EMAIL = 0x0010000000;
|
||||
const TITLE_EMPTY = 0x0100000000;
|
||||
const INVALID_DATE = 0x1000000000;
|
@ -19,60 +19,62 @@
|
||||
|
||||
asort($ALLOWED_LANGUAGES);
|
||||
|
||||
if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang'], array_keys($ALLOWED_LANGUAGES)) ) {
|
||||
$mlocale = $_POST['lang'] ;
|
||||
setcookie('lang' , $_POST['lang'], time()+60*5);
|
||||
} elseif ( isset($_COOKIE['lang']) && is_string($_COOKIE['lang']) && in_array($_COOKIE['lang'], array_keys($ALLOWED_LANGUAGES)) ) {
|
||||
$mlocale = $_COOKIE['lang'] ;
|
||||
if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang'], array_keys($ALLOWED_LANGUAGES))) {
|
||||
$mlocale = $_POST['lang'];
|
||||
$_SESSION['lang'] = $_POST['lang'];
|
||||
} elseif (isset($_SESSION['lang']) && is_string($_SESSION['lang']) && in_array($_SESSION['lang'], array_keys($ALLOWED_LANGUAGES))) {
|
||||
$mlocale = $_SESSION['lang'];
|
||||
} else {
|
||||
|
||||
$mlocale = LANGUE;
|
||||
// Replace config language by browser language if possible
|
||||
foreach ($ALLOWED_LANGUAGES as $k => $v ) {
|
||||
if (substr($k,0,2)==substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)) {
|
||||
foreach ($ALLOWED_LANGUAGES as $k => $v) {
|
||||
if (substr($k, 0, 2) == substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)) {
|
||||
$mlocale = $k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$locale = $mlocale . '.utf8';//unix format
|
||||
if (strtoupper(substr(PHP_OS,0,3))=='WIN'){
|
||||
putenv("LC_ALL=$mlocale"); //Windows env. needed to switch between languages
|
||||
switch ($mlocale){
|
||||
case 'fr_FR' : $locale = "fra";break; //$locale in windows locale format, needed to use php function that handle text : strftime()
|
||||
case 'en_GB' : $locale = "english";break; //see http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.90%29.aspx
|
||||
case 'de_DE' : $locale = "deu";break;
|
||||
case 'es_ES' : $locale = "esp";break;
|
||||
}
|
||||
}
|
||||
|
||||
putenv('LANGUAGE=');//sert à quoi?
|
||||
setlocale(LC_ALL, $locale);
|
||||
setlocale(LC_TIME, $locale);
|
||||
setlocale(LC_MESSAGES, $locale);
|
||||
|
||||
/* Tell PHP which locale to use */
|
||||
$domain = 'Studs';
|
||||
bindtextdomain($domain, 'locale');
|
||||
$locale = $mlocale . '.utf8'; //unix format
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
|
||||
putenv("LC_ALL=$mlocale"); //Windows env. needed to switch between languages
|
||||
switch ($mlocale) {
|
||||
case 'fr_FR' :
|
||||
$locale = "fra";
|
||||
break; //$locale in windows locale format, needed to use php function that handle text : strftime()
|
||||
case 'en_GB' :
|
||||
$locale = "english";
|
||||
break; //see http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.90%29.aspx
|
||||
case 'de_DE' :
|
||||
$locale = "deu";
|
||||
break;
|
||||
case 'es_ES' :
|
||||
$locale = "esp";
|
||||
break;
|
||||
}
|
||||
}
|
||||
putenv('LANG=' . $locale);
|
||||
setlocale(LC_ALL, $locale);
|
||||
bindtextdomain($domain, ROOT_DIR . 'locale');
|
||||
bind_textdomain_codeset($domain, 'UTF-8');
|
||||
textdomain($domain);
|
||||
|
||||
/* temp, for compatibility :*/
|
||||
$a = explode('_', $mlocale);
|
||||
$_SESSION['langue'] = strtoupper($a[0]);
|
||||
|
||||
/* <html lang="$lang"> */
|
||||
$lang = ($_SESSION['langue']!='') ? strtolower($_SESSION['langue']) : 'fr';
|
||||
|
||||
/* <html lang="$html_lang"> */
|
||||
$html_lang = substr($locale, 0, 2);
|
||||
|
||||
/* Date Format */
|
||||
$date_format['txt_full'] = _("%A, den %e. %B %Y"); //summary in choix_date.php and removal date in choix_(date|autre).php
|
||||
$date_format['txt_short'] = "%A %e %B %Y"; // radio title
|
||||
$date_format['txt_day'] = "%a %e";
|
||||
if (strtoupper(substr(PHP_OS,0,3))=='WIN'){ //%e can't be used on Windows platform, use %#d instead
|
||||
foreach($date_format as $k => $v) {
|
||||
$date_format[$k] = preg_replace('#(?<!%)((?:%%)*)%e#','\1%#d', $v); //replace %e by %#d for windows
|
||||
$date_format['txt_full'] = _('%A, den %e. %B %Y'); //summary in choix_date.php and removal date in choix_(date|autre).php
|
||||
$date_format['txt_short'] = _('%A %e %B %Y'); // radio title
|
||||
$date_format['txt_day'] = _('%a %e');
|
||||
$date_format['txt_date'] = _('%Y-%m-%d');
|
||||
$date_format['txt_year_month'] = _('%B %Y');
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { //%e can't be used on Windows platform, use %#d instead
|
||||
foreach ($date_format as $k => $v) {
|
||||
$date_format[$k] = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $v); //replace %e by %#d for windows
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,16 +16,28 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
use Framadate\FramaDB;
|
||||
|
||||
// Autoloading of dependencies with Composer
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
if (session_id() == '') {
|
||||
session_start();
|
||||
}
|
||||
|
||||
if (ini_get('date.timezone') == '') {
|
||||
date_default_timezone_set('Europe/Paris');
|
||||
}
|
||||
// Autoloading of dependencies with Composer
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
include_once __DIR__ . '/constants.php';
|
||||
include_once __DIR__ . '/i18n.php';
|
||||
define('ROOT_DIR', __DIR__ . '/../../');
|
||||
|
||||
$connect = NewADOConnection(BASE_TYPE);
|
||||
$connect->Connect(SERVEURBASE, USERBASE, USERPASSWD, BASE);
|
||||
require_once __DIR__ . '/constants.php';
|
||||
require_once __DIR__ . '/config.php';
|
||||
require_once __DIR__ . '/i18n.php';
|
||||
|
||||
// Smarty
|
||||
require_once __DIR__ . '/smarty.php';
|
||||
|
||||
// Connection to database
|
||||
$connect = new FramaDB(DB_CONNECTION_STRING, DB_USER, DB_PASSWORD);
|
||||
$err = 0;
|
||||
|
51
app/inc/smarty.php
Normal file
51
app/inc/smarty.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* This software is governed by the CeCILL-B license. If a copy of this license
|
||||
* is not distributed with this file, you can obtain one at
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
use Framadate\Utils;
|
||||
|
||||
require_once __DIR__ . '/../../vendor/smarty/smarty/libs/Smarty.class.php';
|
||||
$smarty = new \Smarty();
|
||||
$smarty->setTemplateDir(ROOT_DIR . '/tpl/');
|
||||
$smarty->setCompileDir(ROOT_DIR . '/tpl_c/');
|
||||
$smarty->setCacheDir(ROOT_DIR . '/cache/');
|
||||
$smarty->caching = false;
|
||||
|
||||
$smarty->assign('APPLICATION_NAME', NOMAPPLICATION);
|
||||
$smarty->assign('SERVER_URL', Utils::get_server_name());
|
||||
$smarty->assign('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
|
||||
$smarty->assign('TITLE_IMAGE', IMAGE_TITRE);
|
||||
$smarty->assign('use_nav_js', file_exists($_SERVER['DOCUMENT_ROOT'] . '/nav/nav.js'));
|
||||
$smarty->assign('html_lang', $html_lang);
|
||||
$smarty->assign('langs', $ALLOWED_LANGUAGES);
|
||||
$smarty->assign('date_format', $date_format);
|
||||
|
||||
function smarty_modifier_poll_url($poll_id, $admin = false) {
|
||||
return Utils::getUrlSondage($poll_id, $admin);
|
||||
}
|
||||
|
||||
function smarty_modifier_markdown($md, $clear = false) {
|
||||
return Utils::markdown($md, $clear);
|
||||
}
|
||||
|
||||
function smarty_modifier_resource($link) {
|
||||
return Utils::get_server_name() . $link;
|
||||
}
|
||||
|
||||
function smarty_modifier_html($html) {
|
||||
return Utils::htmlEscape($html);
|
||||
}
|
18
bandeaux.php
18
bandeaux.php
@ -16,7 +16,7 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
@ -28,7 +28,7 @@ function bandeau_titre($titre)
|
||||
echo '
|
||||
<header role="banner">';
|
||||
if(count($ALLOWED_LANGUAGES)>1){
|
||||
echo '<form method="post" action="#">
|
||||
echo '<form method="post" action="" class="hidden-print">
|
||||
<div class="input-group input-group-sm pull-right col-md-2 col-xs-4">
|
||||
<select name="lang" class="form-control" title="'. _("Select the language") .'" >' . liste_lang() . '</select>
|
||||
<span class="input-group-btn">
|
||||
@ -43,16 +43,26 @@ function bandeau_titre($titre)
|
||||
<hr class="trait" role="presentation" />
|
||||
</header>
|
||||
<main role="main">';
|
||||
|
||||
global $connect;
|
||||
$tables = $connect->allTables();
|
||||
$diff = array_diff([Utils::table('comment'), Utils::table('poll'), Utils::table('slot'), Utils::table('vote')], $tables);
|
||||
if (0 != count($diff)) {
|
||||
echo '<div class="alert alert-danger">'. _('Framadate is not properly installed, please check the "INSTALL" to setup the database before continuing.') .'</div>';
|
||||
bandeau_pied();
|
||||
die();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function liste_lang()
|
||||
{
|
||||
global $ALLOWED_LANGUAGES; global $lang;
|
||||
global $ALLOWED_LANGUAGES; global $html_lang;
|
||||
|
||||
$str = '';
|
||||
|
||||
foreach ($ALLOWED_LANGUAGES as $k => $v ) {
|
||||
if (substr($k,0,2)==$lang) {
|
||||
if (substr($k,0,2)==$html_lang) {
|
||||
$str .= '<option lang="'.substr($k,0,2).'" selected value="' . $k . '">' . $v . '</option>' . "\n" ;
|
||||
} else {
|
||||
$str .= '<option lang="'.substr($k,0,2).'" value="' . $k . '">' . $v . '</option>' . "\n" ;
|
||||
|
263
choix_autre.php
263
choix_autre.php
@ -16,10 +16,21 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Choice;
|
||||
|
||||
session_start();
|
||||
include_once('creation_sondage.php');
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Service */
|
||||
/*---------*/
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
|
||||
if (file_exists('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
@ -27,151 +38,190 @@ if (file_exists('bandeaux_local.php')) {
|
||||
include_once('bandeaux.php');
|
||||
}
|
||||
|
||||
// Step 1/3 : error if $_SESSION from info_sondage are not valid
|
||||
if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmpty('nom', $_SESSION) === false || (($config['use_smtp']) ? Utils::issetAndNoEmpty('adresse', $_SESSION) === false : false)) {
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (($config['use_smtp']) ? empty($_SESSION['form']->admin_mail) : false)) {
|
||||
|
||||
Utils::print_header ( _("Error!") );
|
||||
Utils::print_header(_("Error!"));
|
||||
bandeau_titre(_("Error!"));
|
||||
|
||||
echo '
|
||||
<div class="alert alert-danger">
|
||||
<h3>' . _("You haven't filled the first section of the poll creation.") . ' !</h3>
|
||||
<p>' . _("Back to the homepage of ") . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a></p>
|
||||
</div>'."\n";
|
||||
<h3>' . _('You haven\'t filled the first section of the poll creation.') . ' !</h3>
|
||||
<p>' . _('Back to the homepage of') . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a></p>
|
||||
</div>' . "\n";
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
} else {
|
||||
$min_time = time() + 86400;
|
||||
$max_time = time() + (86400 * $config['default_poll_duration']);
|
||||
|
||||
// Step 4 : Data prepare before insert in DB
|
||||
if (isset($_POST["confirmecreation"])) {
|
||||
//recuperation des données de champs textes
|
||||
$temp_results = '';
|
||||
if (isset($_SESSION['choices'])) {
|
||||
for ($i = 0; $i < count($_SESSION['choices']); $i++) {
|
||||
if ($_SESSION['choices'][$i]!="") {
|
||||
$temp_results.=','.str_replace(",", " ", htmlentities(html_entity_decode($_SESSION['choices'][$i], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'));
|
||||
if (isset($_POST['confirmecreation'])) {
|
||||
|
||||
// Define expiration date
|
||||
$enddate = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
$min_time = time() + (24 * 60 * 60);
|
||||
$max_time = time() + (86400 * $config['default_poll_duration']);
|
||||
|
||||
if (!empty($enddate)) {
|
||||
$registredate = explode('/', $enddate);
|
||||
|
||||
if (is_array($registredate) && count($registredate) == 3) {
|
||||
$time = mktime(0, 0, 0, $registredate[1], $registredate[0], $registredate[2]);
|
||||
|
||||
if ($time < $min_time) {
|
||||
$_SESSION['form']->end_date = $min_time;
|
||||
} elseif ($max_time < $time) {
|
||||
$_SESSION['form']->end_date = $max_time;
|
||||
} else {
|
||||
$_SESSION['form']->end_date = $time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$temp_results=substr($temp_results,1);
|
||||
$_SESSION["toutchoix"]=$temp_results;
|
||||
if (empty($_SESSION['form']->end_date)) {
|
||||
// By default, expiration date is 6 months after last day
|
||||
$_SESSION['form']->end_date = $max_time;
|
||||
}
|
||||
|
||||
// format du sondage AUTRE
|
||||
$_SESSION['form']->format = 'A';
|
||||
|
||||
// Insert poll in database
|
||||
$ids = $pollService->createPoll($_SESSION['form']);
|
||||
$poll_id = $ids[0];
|
||||
$admin_poll_id = $ids[1];
|
||||
|
||||
|
||||
if (Utils::issetAndNoEmpty('champdatefin')) {
|
||||
$registredate = explode("/",$_POST["champdatefin"]);
|
||||
if (is_array($registredate) == true && count($registredate) == 3) {
|
||||
$time = mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]);
|
||||
if ($time > time() + (24*60*60)) {
|
||||
$_SESSION["champdatefin"]=$time;
|
||||
// Send confirmation by mail if enabled
|
||||
if ($config['use_smtp'] === true) {
|
||||
$message = _("This is the message you have to send to the people you want to poll. \nNow, you have to send this message to everyone you want to poll.");
|
||||
$message .= "\n\n";
|
||||
$message .= stripslashes(html_entity_decode($_SESSION['form']->admin_name, ENT_QUOTES, "UTF-8")) . ' ' . _('hast just created a poll called') . ' : "' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)) . "\".\n";
|
||||
$message .= _('Thanks for filling the poll at the link above') . " :\n\n%s\n\n" . _('Thanks for your confidence.') . "\n" . NOMAPPLICATION;
|
||||
|
||||
$message_admin = _("This message should NOT be sent to the polled people. It is private for the poll's creator.\n\nYou can now modify it at the link above");
|
||||
$message_admin .= " :\n\n" . "%s \n\n" . _('Thanks for your confidence.') . "\n" . NOMAPPLICATION;
|
||||
|
||||
$message = sprintf($message, Utils::getUrlSondage($poll_id));
|
||||
$message_admin = sprintf($message_admin, Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($_SESSION['form']->admin_mail)) {
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . _('Author\'s message') . '] ' . _('Poll') . ' : ' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)), $message_admin);
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . _('For sending to the polled users') . '] ' . _('Poll') . ' : ' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)), $message);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean Form data in $_SESSION
|
||||
unset($_SESSION['form']);
|
||||
|
||||
// Delete old polls
|
||||
$purgeService->purgeOldPolls();
|
||||
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
exit;
|
||||
|
||||
} // Step 3/4 : Confirm poll creation and choose a removal date
|
||||
else if (isset($_POST['fin_sondage_autre'])) {
|
||||
Utils::print_header(_('Removal date and confirmation (3 on 3)'));
|
||||
bandeau_titre(_('Removal date and confirmation (3 on 3)'));
|
||||
|
||||
|
||||
// Store choices in $_SESSION
|
||||
if (isset($_POST['choices'])) {
|
||||
$_SESSION['form']->clearChoices();
|
||||
foreach ($_POST['choices'] as $c) {
|
||||
if (!empty($c)) {
|
||||
$c = strip_tags($c);
|
||||
$choice = new Choice($c);
|
||||
$_SESSION['form']->addChoice($choice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//format du sondage AUTRE
|
||||
$_SESSION["formatsondage"]="A".$_SESSION["studsplus"];
|
||||
|
||||
ajouter_sondage();
|
||||
|
||||
}
|
||||
|
||||
// recuperation des sujets pour sondage AUTRE
|
||||
if (isset($_POST['choices'])) {
|
||||
$k = 0;
|
||||
for ($i = 0; $i < count($_POST['choices']); $i++) {
|
||||
if (Utils::issetAndNoEmpty($i, $_POST['choices'])) {
|
||||
$_SESSION['choices'][$k]=htmlentities(html_entity_decode($_POST['choices'][$i], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
|
||||
$k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3/3 : Confirm poll creation and choose a removal date
|
||||
if (isset($_POST["fin_sondage_autre"])) {
|
||||
Utils::print_header ( _("Removal date and confirmation (3 on 3)") );
|
||||
bandeau_titre(_("Removal date and confirmation (3 on 3)"));
|
||||
|
||||
// Expiration date is initialised with config parameter. Value will be modified in step 4 if user has defined an other date
|
||||
$_SESSION["champdatefin"]= time()+ (86400 * $config['default_poll_duration']); //60 sec * 60 min * 24 hours * config
|
||||
|
||||
$removal_date= utf8_encode(strftime($date_format['txt_full'], ($_SESSION["champdatefin"])));//textual date
|
||||
$_SESSION['form']->end_date = time() + (86400 * $config['default_poll_duration']); //60 sec * 60 min * 24 hours * config
|
||||
|
||||
// Summary
|
||||
$summary = '<ol>';
|
||||
for ($i=0;$i<count($_SESSION['choices']);$i++) {
|
||||
foreach ($_SESSION['form']->getChoices() as $choice) {
|
||||
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_a); // Markdown [text](href)
|
||||
if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [![alt](src)](href)
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/', $choice->getName(), $md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/', $choice->getName(), $md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/', $choice->getName(), $md_a); // Markdown [text](href)
|
||||
if (isset($md_a_img[2][0]) && $md_a_img[2][0] != '' && isset($md_a_img[3][0]) && $md_a_img[3][0] != '') { // [![alt](src)](href)
|
||||
|
||||
$li_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
$li_subject_html = '<a href="'.$md_a_img[3][0].'"><img src="'.$md_a_img[2][0].'" class="img-responsive" alt="'.$li_subject_text.'" /></a>';
|
||||
$li_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0] != '') ? stripslashes($md_a_img[1][0]) : _('Choice') . ' ' . ($i + 1);
|
||||
$li_subject_html = '<a href="' . $md_a_img[3][0] . '"><img src="' . $md_a_img[2][0] . '" class="img-responsive" alt="' . $li_subject_text . '" /></a>';
|
||||
|
||||
} elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { // ![alt](src)
|
||||
} elseif (isset($md_img[2][0]) && $md_img[2][0] != '') { // ![alt](src)
|
||||
|
||||
$li_subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
$li_subject_html = '<img src="'.$md_img[2][0].'" class="img-responsive" alt="'.$li_subject_text.'" />';
|
||||
$li_subject_text = (isset($md_img[1][0]) && $md_img[1][0] != '') ? stripslashes($md_img[1][0]) : _('Choice') . ' ' . ($i + 1);
|
||||
$li_subject_html = '<img src="' . $md_img[2][0] . '" class="img-responsive" alt="' . $li_subject_text . '" />';
|
||||
|
||||
} elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href)
|
||||
} elseif (isset($md_a[2][0]) && $md_a[2][0] != '') { // [text](href)
|
||||
|
||||
$li_subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1);
|
||||
$li_subject_html = '<a href="'.$md_a[2][0].'">'.$li_subject_text.'</a>';
|
||||
$li_subject_text = (isset($md_a[1][0]) && $md_a[1][0] != '') ? stripslashes($md_a[1][0]) : _('Choice') . ' ' . ($i + 1);
|
||||
$li_subject_html = '<a href="' . $md_a[2][0] . '">' . $li_subject_text . '</a>';
|
||||
|
||||
} else { // text only
|
||||
|
||||
$li_subject_text = stripslashes($_SESSION['choices'][$i]);
|
||||
$li_subject_text = stripslashes($choice->getName());
|
||||
$li_subject_html = $li_subject_text;
|
||||
|
||||
}
|
||||
|
||||
$summary .= '<li>'.$li_subject_html.'</li>'."\n";
|
||||
$summary .= '<li>' . $li_subject_html . '</li>' . "\n";
|
||||
}
|
||||
$summary .= '</ol>';
|
||||
|
||||
$end_date_str = utf8_encode(strftime('%d/%m/%Y', $max_time)); //textual date
|
||||
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::get_server_name() . 'choix_autre.php" method="POST" class="form-horizontal" role="form">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="well summary">
|
||||
<h4>'. _("List of your choices").'</h4>
|
||||
'. $summary .'
|
||||
<h4>' . _('List of your choices') . '</h4>
|
||||
' . $summary . '
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
<p>' . _("Your poll will be automatically removed after"). " " . $config['default_poll_duration'] . " " . _("days") . ': <strong>'.$removal_date.'</strong>.<br />' . _("You can fix another removal date for it.") .'</p>
|
||||
<p>' . _('Your poll will be automatically removed after') . ' ' . $config['default_poll_duration'] . ' ' . _('days') . '.<br />' . _('You can set a closer removal date for it.') . '</p>
|
||||
<div class="form-group">
|
||||
<label for="champdatefin" class="col-sm-5 control-label">'. _("Removal date (optional)") .'</label>
|
||||
<label for="enddate" class="col-sm-5 control-label">' . _('Removal date (optional)') . '</label>
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
|
||||
<input type="text" class="form-control" id="champdatefin" data-date-format="'. _("dd/mm/yyyy") .'" aria-describedby="dateformat" name="champdatefin" value="" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" />
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="' . _('dd/mm/yyyy') . '" aria-describedby="dateformat" name="enddate" value="' . $end_date_str . '" size="10" maxlength="10" placeholder="' . _("dd/mm/yyyy") . '" />
|
||||
</div>
|
||||
</div>
|
||||
<span id="dateformat" class="sr-only">'. _("(dd/mm/yyyy)") .'</span>
|
||||
<span id="dateformat" class="sr-only">' . _('(dd/mm/yyyy)') . '</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning">
|
||||
<p>'. _("Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll."). '</p>';
|
||||
if($config['use_smtp']==true){
|
||||
<p>' . _('Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll.') . '</p>';
|
||||
if ($config['use_smtp'] == true) {
|
||||
echo '
|
||||
<p>' . _("Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.") .'</p>';
|
||||
<p>' . _('Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.') . '</p>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
<p class="text-right">
|
||||
<button class="btn btn-default" onclick="javascript:window.history.back();" title="'. _('Back to step 2') . '">'. _('Back') . '</button>
|
||||
<button name="confirmecreation" value="confirmecreation" type="submit" class="btn btn-success">'. _('Create the poll') . '</button>
|
||||
<button class="btn btn-default" onclick="javascript:window.history.back();" title="' . _('Back to step 2') . '">' . _('Back') . '</button>
|
||||
<button name="confirmecreation" value="confirmecreation" type="submit" class="btn btn-success">' . _('Create the poll') . '</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>'."\n";
|
||||
</form>' . "\n";
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
// Step 2/3 : Select choices of the poll
|
||||
// Step 2/4 : Select choices of the poll
|
||||
} else {
|
||||
Utils::print_header( _("Poll subjects (2 on 3)"));
|
||||
bandeau_titre(_("Poll subjects (2 on 3)"));
|
||||
Utils::print_header(_('Poll subjects (2 on 3)'));
|
||||
bandeau_titre(_('Poll subjects (2 on 3)'));
|
||||
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::get_server_name() . 'choix_autre.php" method="POST" class="form-horizontal" role="form">
|
||||
@ -179,40 +229,41 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp
|
||||
<div class="col-md-8 col-md-offset-2">';
|
||||
echo '
|
||||
<div class="alert alert-info">
|
||||
<p>'. _("To make a generic poll, it's better to propose at least two choices between differents subjects.") .'</p>
|
||||
<p>'. _("You can add or remove additional choices with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></p>';
|
||||
if($config['user_can_add_img_or_link']){
|
||||
echo ' <p>'. _("It's possible to propose links or images by using "). '<a href="http://'.$lang.'.wikipedia.org/wiki/Markdown">'. _("the Markdown syntax") .'</a>.</p>';
|
||||
<p>' . _("To make a generic poll you need to propose at least two choices between differents subjects.") . '</p>
|
||||
<p>' . _("You can add or remove additional choices with the buttons") . ' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">' . _("Remove") . '</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">' . _("Add") . '</span></p>';
|
||||
if ($config['user_can_add_img_or_link']) {
|
||||
echo ' <p>' . _("It's possible to propose links or images by using ") . '<a href="http://' . $html_lang . '.wikipedia.org/wiki/Markdown">' . _("the Markdown syntax") . '</a>.</p>';
|
||||
}
|
||||
echo ' </div>'."\n";
|
||||
echo ' </div>' . "\n";
|
||||
|
||||
// Fields choices : 5 by default
|
||||
$nb_choices = (isset($_SESSION['choices'])) ? max(count($_SESSION['choices']), 5) : 5;
|
||||
$choices = $_SESSION['form']->getChoices();
|
||||
$nb_choices = max(count($choices), 5);
|
||||
for ($i = 0; $i < $nb_choices; $i++) {
|
||||
$choice_value = (isset($_SESSION['choices'][$i])) ? str_replace("\\","",$_SESSION['choices'][$i]) : '';
|
||||
$choice = isset($choices[$i]) ? $choices[$i] : new Choice();
|
||||
echo '
|
||||
<div class="form-group choice-field">
|
||||
<label for="choice'.$i.'" class="col-sm-2 control-label">'. _("Choice") .' '.($i+1).'</label>
|
||||
<label for="choice' . $i . '" class="col-sm-2 control-label">' . _('Choice') . ' ' . ($i + 1) . '</label>
|
||||
<div class="col-sm-10 input-group">
|
||||
<input type="text" class="form-control" name="choices[]" size="40" value="'.$choice_value.'" id="choice'.$i.'" />';
|
||||
if($config['user_can_add_img_or_link']){
|
||||
echo '<span class="input-group-addon btn-link md-a-img" title="'. _("Add a link or an image") .' - '. _("Choice") .' '.($i+1).'" ><span class="glyphicon glyphicon-picture"></span> <span class="glyphicon glyphicon-link"></span></span>';
|
||||
}
|
||||
<input type="text" class="form-control" name="choices[]" size="40" value="' . $choice->getName() . '" id="choice' . $i . '" />';
|
||||
if ($config['user_can_add_img_or_link']) {
|
||||
echo '<span class="input-group-addon btn-link md-a-img" title="' . _('Add a link or an image') . ' - ' . _('Choice') . ' ' . ($i + 1) . '" ><span class="glyphicon glyphicon-picture"></span> <span class="glyphicon glyphicon-link"></span></span>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
</div>'."\n";
|
||||
</div>' . "\n";
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="col-md-4">
|
||||
<div class="btn-group btn-group">
|
||||
<button type="button" id="remove-a-choice" class="btn btn-default" title="'. _("Remove a choice") .'"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span></button>
|
||||
<button type="button" id="add-a-choice" class="btn btn-default" title="'. _("Add a choice") .'"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></button>
|
||||
<button type="button" id="remove-a-choice" class="btn btn-default" title="' . _('Remove a choice') . '"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">' . _('Remove') . '</span></button>
|
||||
<button type="button" id="add-a-choice" class="btn btn-default" title="' . _('Add a choice') . '"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">' . _('Add') . '</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 text-right">
|
||||
<a class="btn btn-default" href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=autre" title="'. _('Back to step 1') . '">'. _('Back') . '</a>
|
||||
<button name="fin_sondage_autre" value="'._('Next').'" type="submit" class="btn btn-success disabled" title="'. _('Go to step 3') . '">'. _('Next') . '</button>
|
||||
<a class="btn btn-default" href="' . Utils::get_server_name() . 'infos_sondage.php?choix_sondage=autre" title="' . _('Back to step 1') . '">' . _('Back') . '</a>
|
||||
<button name="fin_sondage_autre" value="' . _('Next') . '" type="submit" class="btn btn-success disabled" title="' . _('Go to step 3') . '">' . _('Next') . '</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -220,32 +271,32 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">'. _('Close') . '</span></button>
|
||||
<p class="modal-title" id="md-a-imgModalLabel">'. _("Add a link or an image") .'</p>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">' . _('Close') . '</span></button>
|
||||
<p class="modal-title" id="md-a-imgModalLabel">' . _("Add a link or an image") . '</p>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="alert alert-info">'. _("These fields are optional. You can add a link, an image or both.") .'</p>
|
||||
<p class="alert alert-info">' . _("These fields are optional. You can add a link, an image or both.") . '</p>
|
||||
<div class="form-group">
|
||||
<label for="md-img"><span class="glyphicon glyphicon-picture"></span> '. _('URL of the image') . '</label>
|
||||
<label for="md-img"><span class="glyphicon glyphicon-picture"></span> ' . _('URL of the image') . '</label>
|
||||
<input id="md-img" type="text" placeholder="http://…" class="form-control" size="40" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="md-a"><span class="glyphicon glyphicon-link"></span> '. _('Link') . '</label>
|
||||
<label for="md-a"><span class="glyphicon glyphicon-link"></span> ' . _('Link') . '</label>
|
||||
<input id="md-a" type="text" placeholder="http://…" class="form-control" size="40" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="md-text">'. _('Alternative text') . '</label>
|
||||
<label for="md-text">' . _('Alternative text') . '</label>
|
||||
<input id="md-text" type="text" class="form-control" size="40" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">'. _('Cancel') . '</button>
|
||||
<button type="button" class="btn btn-primary">'. _('Add') . '</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">' . _('Cancel') . '</button>
|
||||
<button type="button" class="btn btn-primary">' . _('Add') . '</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>'."\n";
|
||||
</form>' . "\n";
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
|
264
choix_date.php
264
choix_date.php
@ -5,7 +5,7 @@
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
|
||||
*
|
||||
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
|
||||
* Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft https://git.framasoft.org/framasoft/framadate/)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
@ -14,13 +14,25 @@
|
||||
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
|
||||
*
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft https://git.framasoft.org/framasoft/framadate/)
|
||||
*/
|
||||
namespace Framadate;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Choice;
|
||||
|
||||
session_start();
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
include_once('creation_sondage.php');
|
||||
/* Service */
|
||||
/*---------*/
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
|
||||
if (is_readable('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
@ -28,145 +40,169 @@ if (is_readable('bandeaux_local.php')) {
|
||||
include_once('bandeaux.php');
|
||||
}
|
||||
|
||||
// Step 1/3 : error if $_SESSION from info_sondage are not valid
|
||||
if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmpty('nom', $_SESSION) === false || (($config['use_smtp']) ? Utils::issetAndNoEmpty('adresse', $_SESSION) === false : false)) {
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) || ($config['use_smtp'] && !isset($_SESSION['form']->admin_mail))) {
|
||||
|
||||
Utils::print_header ( _("Error!") );
|
||||
bandeau_titre(_("Error!"));
|
||||
Utils::print_header ( _('Error!') );
|
||||
bandeau_titre(_('Error!'));
|
||||
|
||||
echo '
|
||||
<div class="alert alter-danger">
|
||||
<h3>' . _("You haven't filled the first section of the poll creation.") . ' !</h3>
|
||||
<p>' . _("Back to the homepage of ") . ' ' . '<a href="' . Utils::get_server_name() . '">' . NOMAPPLICATION . '</a>.</p>
|
||||
<h3>' . _('You haven\'t filled the first section of the poll creation.') . ' !</h3>
|
||||
<p>' . _('Back to the homepage of ') . ' ' . '<a href="' . Utils::get_server_name() . '">' . NOMAPPLICATION . '</a>.</p>
|
||||
</div>';
|
||||
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
} else {
|
||||
$min_time = time() + 86400;
|
||||
$max_time = time() + (86400 * $config['default_poll_duration']);
|
||||
|
||||
// Step 4 : Data prepare before insert in DB
|
||||
if (Utils::issetAndNoEmpty('confirmation')) {
|
||||
$temp_results = array();
|
||||
$choixdate='';
|
||||
if (Utils::issetAndNoEmpty('totalchoixjour', $_SESSION) === true) {
|
||||
for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) {
|
||||
if(count($_SESSION['horaires'.$i])!=0) {
|
||||
for ($j=0;$j< min(count($_SESSION['horaires'.$i]),12);$j++) {
|
||||
if ($_SESSION['horaires'.$i][$j]!="") {
|
||||
array_push($temp_results, $_SESSION["totalchoixjour"][$i].'@'.$_SESSION['horaires'.$i][$j]);
|
||||
} else {
|
||||
array_push($temp_results, $_SESSION["totalchoixjour"][$i]);
|
||||
}
|
||||
}
|
||||
if (!empty($_POST['confirmation'])) {
|
||||
|
||||
// Define expiration date
|
||||
$enddate = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
|
||||
if (!empty($enddate)) {
|
||||
$registredate = explode('/', $enddate);
|
||||
|
||||
if (is_array($registredate) && count($registredate) == 3) {
|
||||
$time = mktime(0, 0, 0, $registredate[1], $registredate[0], $registredate[2]);
|
||||
|
||||
if ($time < $min_time) {
|
||||
$_SESSION['form']->end_date = $min_time;
|
||||
} elseif ($max_time < $time) {
|
||||
$_SESSION['form']->end_date = $max_time;
|
||||
} else {
|
||||
array_push($temp_results, $_SESSION["totalchoixjour"][$i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sort and remove doublons
|
||||
$temp_results = array_unique($temp_results);
|
||||
sort($temp_results);
|
||||
for ($i=0;$i<count($temp_results);$i++) {
|
||||
if (isset($temp_results[$i])) {
|
||||
$choixdate.=','.$temp_results[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION["toutchoix"]=substr($choixdate,1);
|
||||
|
||||
// Expiration date → 6 months after last day if not filled or in bad format
|
||||
$_SESSION["champdatefin"]=end($temp_results)+(86400 * $config['default_poll_duration']);
|
||||
|
||||
if (Utils::issetAndNoEmpty('champdatefin')) {
|
||||
$registredate = explode("/",$_POST["champdatefin"]);
|
||||
if (is_array($registredate) == true && count($registredate) == 3) {
|
||||
$time = mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]);
|
||||
if ($time > time() + (24*60*60)) {
|
||||
$_SESSION["champdatefin"]=$time;
|
||||
$_SESSION['form']->end_date = $time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ajouter_sondage();
|
||||
if (empty($_SESSION['form']->end_date)) {
|
||||
// By default, expiration date is 6 months after last day
|
||||
$_SESSION['form']->end_date = $max_time;
|
||||
}
|
||||
|
||||
// Insert poll in database
|
||||
$ids = $pollService->createPoll($_SESSION['form']);
|
||||
$poll_id = $ids[0];
|
||||
$admin_poll_id = $ids[1];
|
||||
|
||||
|
||||
// Send confirmation by mail if enabled
|
||||
if ($config['use_smtp'] === true) {
|
||||
$message = _("This is the message you have to send to the people you want to poll. \nNow, you have to send this message to everyone you want to poll.");
|
||||
$message .= "\n\n";
|
||||
$message .= stripslashes(html_entity_decode($_SESSION['form']->admin_name, ENT_QUOTES, 'UTF-8')) . ' ' . _("hast just created a poll called") . ' : "' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)) . "\".\n";
|
||||
$message .= _('Thanks for filling the poll at the link above') . " :\n\n%s\n\n" . _('Thanks for your confidence.') . "\n" . NOMAPPLICATION;
|
||||
|
||||
$message_admin = _("This message should NOT be sent to the polled people. It is private for the poll's creator.\n\nYou can now modify it at the link above");
|
||||
$message_admin .= " :\n\n" . "%s \n\n" . _('Thanks for your confidence.') . "\n" . NOMAPPLICATION;
|
||||
|
||||
$message = sprintf($message, Utils::getUrlSondage($poll_id));
|
||||
$message_admin = sprintf($message_admin, Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($_SESSION['form']->admin_mail)) {
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . _('Author\'s message') . '] ' . _('Poll') . ' : ' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)), $message_admin);
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . _('For sending to the polled users') . '] ' . _('Poll') . ' : ' . stripslashes(htmlspecialchars_decode($_SESSION['form']->title, ENT_QUOTES)), $message);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean Form data in $_SESSION
|
||||
unset($_SESSION['form']);
|
||||
|
||||
// Delete old polls
|
||||
$purgeService->purgeOldPolls();
|
||||
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
exit;
|
||||
|
||||
} else {
|
||||
if (Utils::issetAndNoEmpty('days')) {
|
||||
if (!isset($_SESSION["totalchoixjour"])) {
|
||||
$_SESSION["totalchoixjour"]=array();
|
||||
}
|
||||
$k = 0;
|
||||
for ($i = 0; $i < count($_POST["days"]); $i++) {
|
||||
if (isset($_POST["days"][$i]) && $_POST["days"][$i] !='') {
|
||||
$_SESSION['totalchoixjour'][$k] = mktime(0, 0, 0, substr($_POST["days"][$i],3,2),substr($_POST["days"][$i],0,2),substr($_POST["days"][$i],6,4));
|
||||
|
||||
$l = 0;
|
||||
for($j = 0; $j < count($_POST['horaires'.$i]); $j++) {
|
||||
if (isset($_POST['horaires'.$i][$j]) && $_POST['horaires'.$i][$j] != '') {
|
||||
$_SESSION['horaires'.$k][$l] = $_POST['horaires'.$i][$j];
|
||||
$l++;
|
||||
if (!empty($_POST['days'])) {
|
||||
|
||||
// Clear previous choices
|
||||
$_SESSION['form']->clearChoices();
|
||||
|
||||
for ($i = 0; $i < count($_POST['days']); $i++) {
|
||||
$day = $_POST['days'][$i];
|
||||
|
||||
if (!empty($day)) {
|
||||
// Add choice to Form data
|
||||
$time = mktime(0, 0, 0, substr($_POST["days"][$i],3,2),substr($_POST["days"][$i],0,2),substr($_POST["days"][$i],6,4));
|
||||
$choice = new Choice($time);
|
||||
$_SESSION['form']->addChoice($choice);
|
||||
|
||||
$schedules = $inputService->filterArray($_POST['horaires'.$i], FILTER_DEFAULT);
|
||||
for($j = 0; $j < count($schedules); $j++) {
|
||||
if (!empty($schedules[$j])) {
|
||||
$choice->addSlot(strip_tags($schedules[$j]));
|
||||
}
|
||||
}
|
||||
$k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//le format du sondage est DATE
|
||||
$_SESSION["formatsondage"] = "D".$_SESSION["studsplus"];
|
||||
$_SESSION['form']->format = 'D';
|
||||
|
||||
// Step 3/3 : Confirm poll creation
|
||||
if (Utils::issetAndNoEmpty('choixheures') && Utils::issetAndNoEmpty('totalchoixjour', $_SESSION)) {
|
||||
// Step 3/4 : Confirm poll creation
|
||||
if (!empty($_POST['choixheures']) && !isset($_SESSION['form']->totalchoixjour)) {
|
||||
|
||||
Utils::print_header ( _("Removal date and confirmation (3 on 3)") );
|
||||
bandeau_titre(_("Removal date and confirmation (3 on 3)"));
|
||||
Utils::print_header ( _('Removal date and confirmation (3 on 3)') );
|
||||
bandeau_titre(_('Removal date and confirmation (3 on 3)'));
|
||||
|
||||
$temp_array = array_unique($_SESSION["totalchoixjour"]);
|
||||
sort($temp_array);
|
||||
$removal_date=utf8_encode(strftime($date_format['txt_full'], end($temp_array)+ (86400 * $config['default_poll_duration'])));
|
||||
$_SESSION['form']->sortChoices();
|
||||
$last_date = $_SESSION['form']->lastChoice()->getName();
|
||||
$removal_date = $last_date + (86400 * $config['default_poll_duration']);
|
||||
|
||||
// Sumary
|
||||
// Summary
|
||||
$summary = '<ul>';
|
||||
for ($i=0;$i<count($_SESSION["totalchoixjour"]);$i++) {
|
||||
$summary .= '<li>'.strftime($date_format['txt_full'], $_SESSION["totalchoixjour"][$i]);
|
||||
for ($j=0;$j<count($_SESSION['horaires'.$i]);$j++) {
|
||||
if (isset($_SESSION['horaires'.$i][$j])) {
|
||||
$summary .= ($j==0) ? ' : ' : ', ';
|
||||
$summary .= $_SESSION['horaires'.$i][$j];
|
||||
}
|
||||
foreach ($_SESSION['form']->getChoices() as $choice) {
|
||||
$summary .= '<li>'.strftime($date_format['txt_full'], $choice->getName());
|
||||
$first = true;
|
||||
foreach ($choice->getSlots() as $slots) {
|
||||
$summary .= $first ? ' : ' : ', ';
|
||||
$summary .= $slots;
|
||||
$first = false;
|
||||
}
|
||||
$summary .= '</li>'."\n";
|
||||
$summary .= '</li>';
|
||||
}
|
||||
$summary .= '</ul>';
|
||||
|
||||
$end_date_str = utf8_encode(strftime('%d/%m/%Y', $max_time)); //textual date
|
||||
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::get_server_name() . 'choix_date.php" method="POST" class="form-horizontal" role="form">
|
||||
<div class="row" id="selected-days">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<h3>'. _("Confirm the creation of your poll") .'</h3>
|
||||
<h3>'. _('Confirm the creation of your poll') .'</h3>
|
||||
<div class="well summary">
|
||||
<h4>'. _("List of your choices").'</h4>
|
||||
<h4>'. _('List of your choices').'</h4>
|
||||
'. $summary .'
|
||||
</div>
|
||||
<div class="alert alert-info clearfix">
|
||||
<p>' . _("Your poll will be automatically removed "). $config['default_poll_duration'] . ' ' . _("days") ._(" after the last date of your poll:") . ' <strong>'.$removal_date.'</strong>.<br />' . _("You can fix another removal date for it.") .'</p>
|
||||
<p>' . _('Your poll will be automatically removed '). $config['default_poll_duration'] . ' ' . _('days') . ' ' ._('after the last date of your poll') . '.<br />' . _('You can set a closer removal date for it.') .'</p>
|
||||
<div class="form-group">
|
||||
<label for="champdatefin" class="col-sm-5 control-label">'. _("Removal date (optional)") .'</label>
|
||||
<label for="enddate" class="col-sm-5 control-label">'. _('Removal date') .'</label>
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
|
||||
<input type="text" class="form-control" id="champdatefin" data-date-format="'. _("dd/mm/yyyy") .'" aria-describedby="dateformat" name="champdatefin" value="" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" />
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="'. _('dd/mm/yyyy') .'" aria-describedby="dateformat" name="enddate" value="'.$end_date_str.'" size="10" maxlength="10" placeholder="'. _('dd/mm/yyyy') .'" />
|
||||
</div>
|
||||
</div>
|
||||
<span id="dateformat" class="sr-only">'. _("(dd/mm/yyyy)") .'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning">
|
||||
<p>'. _("Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll."). '</p>';
|
||||
if($config['use_smtp']==true){
|
||||
echo '
|
||||
<p>' . _("Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.") .'</p>';
|
||||
<p>'. _('Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll.'). '</p>';
|
||||
if($config['use_smtp'] == true) {
|
||||
echo '<p>' . _('Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.') .'</p>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
@ -180,45 +216,45 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
// Step 2/3 : Select dates of the poll
|
||||
// Step 2/4 : Select dates of the poll
|
||||
} else {
|
||||
Utils::print_header ( _("Poll dates (2 on 3)") );
|
||||
bandeau_titre(_("Poll dates (2 on 3)"));
|
||||
Utils::print_header ( _('Poll dates (2 on 3)') );
|
||||
bandeau_titre(_('Poll dates (2 on 3)'));
|
||||
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::get_server_name() . 'choix_date.php" method="POST" class="form-horizontal" role="form">
|
||||
<div class="row" id="selected-days">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
<h3>'. _("Choose the dates of your poll") .'</h3>
|
||||
<h3>'. _('Choose the dates of your poll') .'</h3>
|
||||
<div class="alert alert-info">
|
||||
<p>'. _("To schedule an event, it's better to propose at least two choices (two hours for one day or two days).").'</p>
|
||||
<p>'. _("You can add or remove additionnal days and hours with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></p>
|
||||
<p>'. _("For each selected day, you can choose, or not, meeting hours (e.g.: \"8h\", \"8:30\", \"8h-10h\", \"evening\", etc.)").'</p>
|
||||
<p>'. _('To schedule an event you need to propose at least two choices (two hours for one day or two days).').'</p>
|
||||
<p>'. _('You can add or remove additionnal days and hours with the buttons') .' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _('Remove') .'</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _('Add') .'</span></p>
|
||||
<p>'. _('For each selected day, you can choose, or not, meeting hours (e.g.: "8h", "8:30", "8h-10h", "evening", etc.)').'</p>
|
||||
</div>';
|
||||
|
||||
// Fields days : 3 by default
|
||||
$nb_days = (isset($_SESSION["totalchoixjour"])) ? count($_SESSION["totalchoixjour"]) : 3;
|
||||
$nb_days = (isset($_SESSION['totalchoixjour'])) ? count($_SESSION['totalchoixjour']) : 3;
|
||||
for ($i=0;$i<$nb_days;$i++) {
|
||||
$day_value = isset($_SESSION["totalchoixjour"][$i]) ? strftime( "%d/%m/%Y", $_SESSION["totalchoixjour"][$i]) : '';
|
||||
$day_value = isset($_SESSION['totalchoixjour'][$i]) ? strftime('%d/%m/%Y', $_SESSION['totalchoixjour'][$i]) : '';
|
||||
echo '
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<legend>
|
||||
<label class="sr-only" for="day'.$i.'">'. _("Day") .' '. ($i+1) .'</label>
|
||||
<label class="sr-only" for="day'.$i.'">'. _('Day') .' '. ($i+1) .'</label>
|
||||
<div class="input-group date col-xs-7">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
|
||||
<input type="text" class="form-control" id="day'.$i.'" title="'. _("Day") .' '. ($i+1) .'" data-date-format="'. _("dd/mm/yyyy") .'" aria-describedby="dateformat'.$i.'" name="days[]" value="'.$day_value.'" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" />
|
||||
<input type="text" class="form-control" id="day'.$i.'" title="'. _("Day") .' '. ($i+1) .'" data-date-format="'. _('dd/mm/yyyy') .'" aria-describedby="dateformat'.$i.'" name="days[]" value="'.$day_value.'" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" />
|
||||
</div>
|
||||
<span id="dateformat'.$i.'" class="sr-only">'. _("(dd/mm/yyyy)") .'</span>
|
||||
<span id="dateformat'.$i.'" class="sr-only">'. _('(dd/mm/yyyy)') .'</span>
|
||||
</legend>'."\n";
|
||||
|
||||
// Fields hours : 3 by default
|
||||
for ($j=0;$j<max(count(isset($_SESSION["horaires".$i]) ? $_SESSION["horaires".$i] : 0),3);$j++) {
|
||||
$hour_value = isset($_SESSION["horaires".$i][$j]) ? $_SESSION["horaires".$i][$j] : '';
|
||||
for ($j=0;$j<max(count(isset($_SESSION['horaires'.$i]) ? $_SESSION['horaires'.$i] : 0),3);$j++) {
|
||||
$hour_value = isset($_SESSION['horaires'.$i][$j]) ? $_SESSION['horaires'.$i][$j] : '';
|
||||
echo '
|
||||
<div class="col-sm-2">
|
||||
<label for="d'.$i.'-h'.$j.'" class="sr-only control-label">'. _("Time") .' '. ($j+1) .'</label>
|
||||
<input type="text" class="form-control hours" title="'.$day_value.' - '. _("Time") .' '. ($j+1) .'" placeholder="'. _("Time") .' '. ($j+1) .'" id="d'.$i.'-h'.$j.'" name="horaires'.$i.'[]" value="'.$hour_value.'" />
|
||||
<label for="d'.$i.'-h'.$j.'" class="sr-only control-label">'. _('Time') .' '. ($j+1) .'</label>
|
||||
<input type="text" class="form-control hours" title="'.$day_value.' - '. _('Time') .' '. ($j+1) .'" placeholder="'. _('Time') .' '. ($j+1) .'" id="d'.$i.'-h'.$j.'" name="horaires'.$i.'[]" value="'.$hour_value.'" />
|
||||
</div>'."\n";
|
||||
}
|
||||
echo '
|
||||
@ -231,24 +267,24 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp
|
||||
}
|
||||
echo '
|
||||
<div class="col-md-4">
|
||||
<button type="button" id="copyhours" class="btn btn-default disabled" title="'. _("Copy hours of the first day") .'"><span class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span><span class="sr-only">'. _("Copy hours of the first day") .'</span></button>
|
||||
<button type="button" id="copyhours" class="btn btn-default disabled" title="'. _('Copy hours of the first day') .'"><span class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span><span class="sr-only">'. _("Copy hours of the first day") .'</span></button>
|
||||
<div class="btn-group btn-group">
|
||||
<button type="button" id="remove-a-day" class="btn btn-default disabled" title="'. _("Remove a day") .'"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove a day") .'</span></button>
|
||||
<button type="button" id="add-a-day" class="btn btn-default" title="'. _("Add a day") .'"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add a day") .'</span></button>
|
||||
<button type="button" id="remove-a-day" class="btn btn-default disabled" title="'. _('Remove a day') .'"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove a day") .'</span></button>
|
||||
<button type="button" id="add-a-day" class="btn btn-default" title="'. _('Add a day') .'"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add a day") .'</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 text-right">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span> '. _("Remove") . ' <span class="caret"></span>
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span> '. _('Remove') . ' <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a id="resetdays" href="javascript:void(0)">'. _("Remove all days") .'</a></li>
|
||||
<li><a id="resethours" href="javascript:void(0)">'. _("Remove all hours") .'</a></li>
|
||||
<li><a id="resetdays" href="javascript:void(0)">'. _('Remove all days') .'</a></li>
|
||||
<li><a id="resethours" href="javascript:void(0)">'. _('Remove all hours') .'</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="btn btn-default" href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=date" title="'. _('Back to step 1') . '">'. _('Back') . '</a>
|
||||
<button name="choixheures" value="'. _("Next") .'" type="submit" class="btn btn-success disabled" title="'. _('Go to step 3') . '">'. _("Next") .'</button>
|
||||
<button name="choixheures" value="'. _('Next') .'" type="submit" class="btn btn-success disabled" title="'. _('Go to step 3') . '">'. _("Next") .'</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,16 +4,18 @@
|
||||
"keywords": [
|
||||
"poll"
|
||||
],
|
||||
"version": "0.8.0",
|
||||
"version": "0.9.0",
|
||||
"license": "CeCILL-B",
|
||||
|
||||
"type": "project",
|
||||
|
||||
"require": {
|
||||
"adodb/adodb-php": "5.19"
|
||||
"smarty/smarty": "3.1.21"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-0": {"Framadate": "app/classes/"}
|
||||
"psr-4": {
|
||||
"Framadate\\": "app/classes/Framadate/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
72
composer.lock
generated
72
composer.lock
generated
@ -4,70 +4,70 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "3cdb051814926a50182b00bbf5297ed2",
|
||||
"hash": "4bf9a3fa30eb400c9ed140dd2d6fa266",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adodb/adodb-php",
|
||||
"version": "v5.19",
|
||||
"name": "smarty/smarty",
|
||||
"version": "v3.1.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ADOdb/ADOdb.git",
|
||||
"reference": "773bb9b7ccd81b403bf75f7ef476c3f2d7ee04de"
|
||||
"url": "https://github.com/smarty-php/smarty.git",
|
||||
"reference": "1f878e6d746ecc8ec8d00d9c75044cf7d23ad94a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ADOdb/ADOdb/zipball/773bb9b7ccd81b403bf75f7ef476c3f2d7ee04de",
|
||||
"reference": "773bb9b7ccd81b403bf75f7ef476c3f2d7ee04de",
|
||||
"url": "https://api.github.com/repos/smarty-php/smarty/zipball/1f878e6d746ecc8ec8d00d9c75044cf7d23ad94a",
|
||||
"reference": "1f878e6d746ecc8ec8d00d9c75044cf7d23ad94a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
"php": ">=5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"adodb.inc.php"
|
||||
"classmap": [
|
||||
"libs/Smarty.class.php",
|
||||
"libs/SmartyBC.class.php",
|
||||
"libs/sysplugins/smarty_security.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1",
|
||||
" BSD-2-Clause"
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "John Lim",
|
||||
"email": "jlim@natsoft.com",
|
||||
"role": "Author"
|
||||
"name": "Monte Ohrt",
|
||||
"email": "monte@ohrt.com"
|
||||
},
|
||||
{
|
||||
"name": "Damien Regad",
|
||||
"role": "Current maintainer"
|
||||
"name": "Uwe Tews",
|
||||
"email": "uwe.tews@googlemail.com"
|
||||
},
|
||||
{
|
||||
"name": "Rodney Rehm",
|
||||
"email": "rodney.rehm@medialize.de"
|
||||
}
|
||||
],
|
||||
"description": "ADOdb is a PHP database abstraction layer library",
|
||||
"homepage": "http://adodb.sourceforge.net/",
|
||||
"description": "Smarty - the compiling PHP template engine",
|
||||
"homepage": "http://www.smarty.net",
|
||||
"keywords": [
|
||||
"database"
|
||||
"templating"
|
||||
],
|
||||
"time": "2014-04-23 14:37:03"
|
||||
"time": "2014-10-31 04:22:20"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [
|
||||
|
||||
],
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"platform": [
|
||||
|
||||
],
|
||||
"platform-dev": [
|
||||
|
||||
]
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": []
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ a.text-info:focus {
|
||||
.text-warning,
|
||||
.text-warning a,
|
||||
a.text-warning {
|
||||
color: #8A6E3B;
|
||||
color: #C05827;
|
||||
}
|
||||
.text-warning a:hover,
|
||||
.text-warning a:focus,
|
||||
@ -85,7 +85,7 @@ a.bg-primary:hover {
|
||||
background-color: #FCF3E3;
|
||||
}
|
||||
.bg-danger,a.bg-danger:hover {
|
||||
background-color: #F2E7E5;
|
||||
background-color: #FDE0DC;
|
||||
}
|
||||
|
||||
/* Alerts */
|
||||
@ -210,6 +210,7 @@ fieldset[disabled] .btn-primary.active {
|
||||
color: #fff;
|
||||
background-color: #849551;
|
||||
border-color: #748544;
|
||||
text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus,
|
||||
@ -434,3 +435,8 @@ fieldset[disabled] .btn-link:focus {
|
||||
.modal-header h4,.modal-header h5,.modal-header h6 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
/* Admin > Polls */
|
||||
.table-polls .cell-format {
|
||||
vertical-align: middle
|
||||
}
|
@ -4,16 +4,12 @@ body {
|
||||
background:none;
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
page-break-after:always;
|
||||
table {
|
||||
page-break-after:always}
|
||||
}
|
||||
|
||||
table {
|
||||
page-break-after:always;
|
||||
}
|
||||
|
||||
table {
|
||||
page-break-inside:auto;
|
||||
page-break-inside:auto
|
||||
}
|
||||
|
||||
tr {
|
||||
@ -29,26 +25,6 @@ tfoot {
|
||||
display:table-footer-group;
|
||||
}
|
||||
|
||||
#tableContainer {
|
||||
overflow-x:visible !important;
|
||||
}
|
||||
|
||||
#vote-form, .scroll-buttons, form .alert.alert-info {
|
||||
display:none;
|
||||
}
|
||||
|
||||
table.results td {
|
||||
border:2px solid #333;
|
||||
}
|
||||
|
||||
table.results tr td:last-child {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.container {
|
||||
width:auto;
|
||||
}
|
||||
|
||||
@page {
|
||||
size:landscape;
|
||||
}
|
||||
|
@ -120,7 +120,9 @@ caption {
|
||||
#title-form h3 .btn-edit,
|
||||
#email-form .btn-edit,
|
||||
#description-form .btn-edit,
|
||||
#poll-rules-form .btn-edit {
|
||||
#poll-rules-form .btn-edit,
|
||||
#expiration-form .btn-edit,
|
||||
#name-form .btn-edit {
|
||||
position:absolute;
|
||||
left:-2000px;
|
||||
}
|
||||
@ -132,7 +134,11 @@ caption {
|
||||
#description-form .btn-edit:focus,
|
||||
#description-form:hover .btn-edit,
|
||||
#poll-rules-form .btn-edit:focus,
|
||||
#poll-rules-form:hover .btn-edit {
|
||||
#poll-rules-form:hover .btn-edit,
|
||||
#expiration-form .btn-edit:focus,
|
||||
#expiration-form:hover .btn-edit,
|
||||
#name-form .btn-edit:focus,
|
||||
#name-form:hover .btn-edit {
|
||||
position:relative !important;
|
||||
left:0;
|
||||
padding: 0px 10px;
|
||||
@ -245,18 +251,13 @@ table.results .btn-link.btn-sm {
|
||||
|
||||
#vote-form td {
|
||||
border-top:2px solid white;
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.yes input, .ifneedbe input,.no input {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0px, 0px, 0px, 0px);
|
||||
border: 0px none;
|
||||
position:absolute;
|
||||
left:0;
|
||||
margin-left:-15px;
|
||||
margin-top:0;
|
||||
}
|
||||
|
||||
.choice input:focus + label {
|
||||
@ -274,47 +275,45 @@ table.results .btn-link.btn-sm {
|
||||
|
||||
.yes .btn, .ifneedbe .btn, .no .btn {
|
||||
width:32px;
|
||||
color:#555;
|
||||
}
|
||||
|
||||
.yes .btn,.yes .btn:hover {
|
||||
.yes .btn {
|
||||
border-bottom-right-radius:0px !important;
|
||||
border-bottom-left-radius:0px !important;
|
||||
margin-bottom:-1px !important;
|
||||
margin-top:4px !important;
|
||||
color:#677835;
|
||||
}
|
||||
|
||||
.ifneedbe .btn,.ifneedbe .btn:hover {
|
||||
.ifneedbe .btn {
|
||||
border-radius:0px;
|
||||
color:#C48A1B;
|
||||
}
|
||||
|
||||
.no .btn,.no .btn:hover{
|
||||
.no .btn{
|
||||
border-top-right-radius:0px !important;
|
||||
border-top-left-radius:0px !important;
|
||||
margin-bottom:4px !important;
|
||||
margin-top:-1px !important;
|
||||
color:#AD220F;
|
||||
}
|
||||
|
||||
.yes input[type="radio"]:checked + label { /* =.btn-success.active */
|
||||
color: #FFF;
|
||||
background-color: #7D8C3F;
|
||||
border-color: #7D8C3F;
|
||||
color: #fff;
|
||||
background-color: #768745;
|
||||
border-color: #67753C;
|
||||
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset;
|
||||
}
|
||||
|
||||
.ifneedbe input[type="radio"]:checked + label { /* =.btn-warning.active */
|
||||
color: #FFF;
|
||||
background-color: #C48A1B;
|
||||
border-color: #C48A1B;
|
||||
color: #fff;
|
||||
background-color: #CF9800;
|
||||
border-color: #BD8A00;
|
||||
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset;
|
||||
}
|
||||
|
||||
.no input[type="radio"]:checked + label { /* =.btn-danger.active */
|
||||
color: #FFF;
|
||||
background-color: #B82E12;
|
||||
border-color: #B82E12;
|
||||
color: #fff;
|
||||
background-color: #BF2511;
|
||||
border-color: #AD220F;
|
||||
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset;
|
||||
}
|
||||
|
||||
|
148
exportcsv.php
148
exportcsv.php
@ -16,89 +16,103 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
if(!isset($_GET['numsondage']) || ! preg_match(";^[\w\d]{16}$;i", $_GET['numsondage'])) {
|
||||
header('Location: studs.php');
|
||||
ob_start();
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
$poll_id = null;
|
||||
$poll = null;
|
||||
|
||||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if (!empty($_GET['poll'])) {
|
||||
$poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^[a-z0-9]+$/']]);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
|
||||
$sql = 'SELECT * FROM user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users';
|
||||
$sql = $connect->Prepare($sql);
|
||||
$user_studs = $connect->Execute($sql, array($_GET['numsondage']));
|
||||
if (!$poll) {
|
||||
$smarty->assign('error', _('This poll doesn\'t exist !'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
$dsondage = Utils::get_sondage_from_id($_GET['numsondage']);
|
||||
$nbcolonnes=substr_count($dsondage->sujet,',')+1;
|
||||
|
||||
$toutsujet=explode(",",$dsondage->sujet);
|
||||
$slots = $pollService->allSlotsByPollId($poll_id);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
|
||||
//affichage des sujets du sondage
|
||||
$input =",";
|
||||
foreach ($toutsujet as $value) {
|
||||
if ($dsondage->format=="D"||$dsondage->format=="D+") {
|
||||
if (strpos($dsondage->sujet,'@') !== false) {
|
||||
$days=explode("@",$value);
|
||||
$input.= '"'.date("j/n/Y",$days[0]).'",';
|
||||
} else {
|
||||
$input.= '"'.date("j/n/Y",$values).'",';
|
||||
}
|
||||
} else {
|
||||
// CSV header
|
||||
if ($poll->format === 'D') {
|
||||
$titles_line = ',';
|
||||
$moments_line = ',';
|
||||
foreach ($slots as $slot) {
|
||||
$title = Utils::csvEscape(strftime($date_format['txt_date'], $slot->title));
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$value,$md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/',$value,$md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/',$value,$md_a); // Markdown [text](href)
|
||||
if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [![alt](src)](href)
|
||||
$subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
} elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { // ![alt](src)
|
||||
$subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
} elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href)
|
||||
$subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1);
|
||||
} else { // text only
|
||||
$subject_text = stripslashes($value);
|
||||
}
|
||||
$input.= '"'.html_entity_decode($subject_text).'",';
|
||||
$titles_line .= str_repeat($title . ',', count($moments));
|
||||
$moments_line .= implode(',', array_map('\Framadate\Utils::csvEscape', $moments)) . ',';
|
||||
}
|
||||
}
|
||||
|
||||
$input.="\r\n";
|
||||
|
||||
if (strpos($dsondage->sujet,'@') !== false) {
|
||||
$input.=",";
|
||||
foreach ($toutsujet as $value) {
|
||||
$heures=explode("@",$value);
|
||||
$input.= '"'.$heures[1].'",';
|
||||
echo $titles_line . "\r\n";
|
||||
echo $moments_line . "\r\n";
|
||||
} else {
|
||||
echo ',';
|
||||
foreach ($slots as $slot) {
|
||||
echo Utils::markdown($slot->title, true) . ',';
|
||||
}
|
||||
|
||||
$input.="\r\n";
|
||||
echo "\r\n";
|
||||
}
|
||||
// END - CSV header
|
||||
|
||||
while ( $data=$user_studs->FetchNextObject(false)) {
|
||||
// Le nom de l'utilisateur
|
||||
$nombase=html_entity_decode(str_replace("°","'",$data->nom));
|
||||
$input.= '"'.$nombase.'",';
|
||||
//affichage des resultats
|
||||
$ensemblereponses=$data->reponses;
|
||||
for ($k=0;$k<$nbcolonnes;$k++) {
|
||||
$car=substr($ensemblereponses,$k,1);
|
||||
switch ($car) {
|
||||
case "1": $input .= '"'._('Yes').'",'; $somme[$k]++; break;
|
||||
case "2": $input .= '"'._('Ifneedbe').'",'; break;
|
||||
default: $input .= '"'._('No').'",'; break;
|
||||
// Vote lines
|
||||
foreach ($votes as $vote) {
|
||||
echo Utils::csvEscape($vote->name) . ',';
|
||||
$choices = str_split($vote->choices);
|
||||
foreach ($choices as $choice) {
|
||||
switch ($choice) {
|
||||
case 0:
|
||||
$text = _('No');
|
||||
break;
|
||||
case 1:
|
||||
$text = _('Ifneedbe');
|
||||
break;
|
||||
case 2:
|
||||
$text = _('Yes');
|
||||
break;
|
||||
default:
|
||||
$text = 'unkown';
|
||||
}
|
||||
echo Utils::csvEscape($text);
|
||||
echo ',';
|
||||
}
|
||||
|
||||
$input.="\r\n";
|
||||
echo "\r\n";
|
||||
}
|
||||
// END - Vote lines
|
||||
|
||||
$filesize = strlen( $input );
|
||||
$filename=$_GET["numsondage"].".csv";
|
||||
// HTTP headers
|
||||
$content = ob_get_clean();
|
||||
$filesize = strlen($content);
|
||||
$filename = Utils::cleanFilename($poll->title) . '.csv';
|
||||
|
||||
header( 'Content-Type: text/csv; charset=utf-8' );
|
||||
header( 'Content-Length: '.$filesize );
|
||||
header( 'Content-Disposition: attachment; filename="'.$filename.'"' );
|
||||
header( 'Cache-Control: max-age=10' );
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Length: ' . $filesize);
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Cache-Control: max-age=10');
|
||||
// END - HTTP headers
|
||||
|
||||
echo str_replace('"','""',$input);
|
||||
|
||||
die();
|
||||
echo $content;
|
||||
|
@ -18,8 +18,6 @@
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
if (is_readable('bandeaux_local.php')) {
|
||||
@ -28,12 +26,9 @@ if (is_readable('bandeaux_local.php')) {
|
||||
include_once('bandeaux.php');
|
||||
}
|
||||
|
||||
session_start();
|
||||
|
||||
// affichage de la page
|
||||
Utils::print_header( _("Home") );
|
||||
bandeau_titre(_("Make your polls"));
|
||||
|
||||
echo '
|
||||
<div class="row">
|
||||
<div class="col-md-6 text-center">
|
||||
|
@ -18,127 +18,112 @@
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
session_start();
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
function fromPostOrEmpty($postKey) {
|
||||
return isset($_POST[$postKey]) ? Utils::htmlEscape($_POST[$postKey]) : '';
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['form'])) {
|
||||
$_SESSION['form'] = new Form();
|
||||
}
|
||||
|
||||
if (file_exists('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
} else {
|
||||
include_once('bandeaux.php');
|
||||
}
|
||||
|
||||
// Type de sondage : <button value="$_SESSION["choix_sondage"]">
|
||||
// Type de sondage : <button value="$_SESSION['form']->choix_sondage">
|
||||
if ((isset($_GET['choix_sondage']) && $_GET['choix_sondage'] == 'date') ||
|
||||
(isset($_POST["choix_sondage"]) && $_POST["choix_sondage"] == 'creation_sondage_date')) {
|
||||
$choix_sondage = "creation_sondage_date";
|
||||
$_SESSION["choix_sondage"] = $choix_sondage;
|
||||
$_SESSION['form']->choix_sondage = $choix_sondage;
|
||||
} else {
|
||||
$choix_sondage = "creation_sondage_autre";
|
||||
$_SESSION["choix_sondage"] = $choix_sondage;
|
||||
$_SESSION['form']->choix_sondage = $choix_sondage;
|
||||
}
|
||||
|
||||
// On teste toutes les variables pour supprimer l'ensemble des warnings PHP
|
||||
// On transforme en entites html les données afin éviter les failles XSS
|
||||
$post_var = array('poursuivre', 'titre', 'nom', 'adresse', 'commentaires', 'studsplus', 'mailsonde', 'creation_sondage_date', 'creation_sondage_autre');
|
||||
foreach ($post_var as $var) {
|
||||
if (isset($_POST[$var]) === true) {
|
||||
$$var = htmlentities($_POST[$var], ENT_QUOTES, 'UTF-8');
|
||||
} else {
|
||||
$$var = null;
|
||||
}
|
||||
}
|
||||
// We clean the data
|
||||
$poursuivre = filter_input(INPUT_POST, 'poursuivre', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^(creation_sondage_date|creation_sondage_autre)$/']]);
|
||||
$title = filter_input(INPUT_POST, 'title', FILTER_SANITIZE_STRING);
|
||||
$name = filter_input(INPUT_POST, 'name', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]);
|
||||
$mail = filter_input(INPUT_POST, 'mail', FILTER_VALIDATE_EMAIL);
|
||||
$description = filter_input(INPUT_POST, 'description', FILTER_SANITIZE_STRING);
|
||||
$editable = filter_input(INPUT_POST, 'editable', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
$receiveNewVotes = filter_input(INPUT_POST, 'receiveNewVotes', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
$receiveNewComments = filter_input(INPUT_POST, 'receiveNewComments', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
|
||||
// On initialise egalement la session car sinon bonjour les warning :-)
|
||||
$session_var = array('titre', 'nom', 'adresse', 'commentaires', 'mailsonde', 'studsplus', );
|
||||
foreach ($session_var as $var) {
|
||||
if (Utils::issetAndNoEmpty($var, $_SESSION) === false) {
|
||||
$_SESSION[$var] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// On initialise également les autres variables
|
||||
$erreur_adresse = false;
|
||||
$erreur_injection_titre = false;
|
||||
$erreur_injection_nom = false;
|
||||
$erreur_injection_commentaires = false;
|
||||
$cocheplus = '';
|
||||
$cochemail = '';
|
||||
$error_on_mail = false;
|
||||
$error_on_title = false;
|
||||
$error_on_name = false;
|
||||
$error_on_description = false;
|
||||
|
||||
#tests
|
||||
if (Utils::issetAndNoEmpty("poursuivre")){
|
||||
$_SESSION["titre"] = $titre;
|
||||
$_SESSION["nom"] = $nom;
|
||||
$_SESSION["adresse"] = $adresse;
|
||||
$_SESSION["commentaires"] = $commentaires;
|
||||
if (!empty($_POST['poursuivre'])) {
|
||||
$_SESSION['form']->title = $title;
|
||||
$_SESSION['form']->admin_name = $name;
|
||||
$_SESSION['form']->admin_mail = $mail;
|
||||
$_SESSION['form']->description = $description;
|
||||
$_SESSION['form']->editable = ($editable !== null) ? true : false;
|
||||
$_SESSION['form']->receiveNewVotes = ($receiveNewVotes !== null) ? true : false;
|
||||
$_SESSION['form']->receiveNewComments = ($receiveNewComments !== null) ? true : false;
|
||||
|
||||
unset($_SESSION["studsplus"]);
|
||||
$_SESSION["studsplus"] = ($studsplus !== null) ? '+' : $_SESSION["studsplus"] = '';
|
||||
|
||||
unset($_SESSION["mailsonde"]);
|
||||
$_SESSION["mailsonde"] = ($mailsonde !== null) ? true : false;
|
||||
|
||||
if ($config['use_smtp']==true){
|
||||
if (Utils::isValidEmail($adresse) === false) {
|
||||
$erreur_adresse = true;
|
||||
if ($config['use_smtp']==true) {
|
||||
if (empty($mail)) {
|
||||
$error_on_mail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match(';<|>|";',$titre)) {
|
||||
$erreur_injection_titre = true;
|
||||
if ($title !== $_POST['title']) {
|
||||
$error_on_title = true;
|
||||
}
|
||||
|
||||
if (preg_match(';<|>|";',$nom)) {
|
||||
$erreur_injection_nom = true;
|
||||
if ($name !== $_POST['name']) {
|
||||
$error_on_name = true;
|
||||
}
|
||||
|
||||
if (preg_match(';<|>|";',$commentaires)) {
|
||||
$erreur_injection_commentaires = true;
|
||||
if ($description !== $_POST['description']) {
|
||||
$error_on_description = true;
|
||||
}
|
||||
|
||||
// Si pas d'erreur dans l'adresse alors on change de page vers date ou autre
|
||||
if($config['use_smtp']==true){
|
||||
$email_OK = $adresse && !$erreur_adresse;
|
||||
} else{
|
||||
if ($config['use_smtp'] == true) {
|
||||
$email_OK = $mail && !$error_on_mail;
|
||||
} else {
|
||||
$email_OK = true;
|
||||
}
|
||||
|
||||
if ($titre && $nom && $email_OK && ! $erreur_injection_titre && ! $erreur_injection_commentaires && ! $erreur_injection_nom) {
|
||||
if ($title && $name && $email_OK && ! $error_on_title && ! $error_on_description && ! $error_on_name) {
|
||||
|
||||
if ( $poursuivre == "creation_sondage_date" ) {
|
||||
header("Location:choix_date.php");
|
||||
if ( $poursuivre == 'creation_sondage_date' ) {
|
||||
header('Location:choix_date.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
if ( $poursuivre == "creation_sondage_autre" ) {
|
||||
header("Location:choix_autre.php");
|
||||
if ( $poursuivre == 'creation_sondage_autre' ) {
|
||||
header('Location:choix_autre.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Title Erreur !
|
||||
Utils::print_header( _("Error!").' - '._("Poll creation (1 on 3)") );
|
||||
Utils::print_header( _('Error!').' - '._('Poll creation (1 on 3)') );
|
||||
}
|
||||
} else {
|
||||
// Title OK (formulaire pas encore rempli)
|
||||
Utils::print_header( _("Poll creation (1 on 3)") );
|
||||
Utils::print_header( _('Poll creation (1 on 3)') );
|
||||
}
|
||||
|
||||
bandeau_titre( _("Poll creation (1 on 3)") );
|
||||
|
||||
// premier sondage ? test l'existence des schémas SQL avant d'aller plus loin
|
||||
if(!Utils::check_table_sondage()) {
|
||||
echo '<div class="alert alert-danger text-center">' . _("Framadate is not properly installed, please check the 'INSTALL' to setup the database before continuing.") . "</div>"."\n";
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
die();
|
||||
}
|
||||
bandeau_titre( _('Poll creation (1 on 3)') );
|
||||
|
||||
/*
|
||||
* Préparation des messages d'erreur
|
||||
*/
|
||||
|
||||
$errors = array(
|
||||
$errors = array (
|
||||
'title' => array (
|
||||
'msg' => '',
|
||||
'aria' => '',
|
||||
@ -161,100 +146,108 @@ $errors = array(
|
||||
)
|
||||
);
|
||||
|
||||
if (!$_SESSION["titre"] && Utils::issetAndNoEmpty("poursuivre") ) {
|
||||
$errors['title']['aria'] = 'aria-describeby="poll_title_error" '; $errors['title']['class'] = ' has-error';
|
||||
$errors['title']['msg'] = '<div class="alert alert-danger" ><p id="poll_title_error">' . _("Enter a title") . '</p></div>';
|
||||
} elseif ($erreur_injection_titre) {
|
||||
$errors['title']['aria'] = 'aria-describeby="poll_title_error" '; $errors['title']['class'] = ' has-error';
|
||||
$errors['title']['inject'] = '<div class="alert alert-danger"><p id="poll_title_error">' . _("Characters < > and \" are not permitted") . '</p></div>';
|
||||
}
|
||||
if (!empty($_POST['poursuivre'])) {
|
||||
if (empty($_POST['title'])) {
|
||||
$errors['title']['aria'] = 'aria-describeby="poll_title_error" ';
|
||||
$errors['title']['class'] = ' has-error';
|
||||
$errors['title']['msg'] = '<div class="alert alert-danger" ><p id="poll_title_error">' . _('Enter a title') . '</p></div>';
|
||||
} elseif ($error_on_title) {
|
||||
$errors['title']['aria'] = 'aria-describeby="poll_title_error" ';
|
||||
$errors['title']['class'] = ' has-error';
|
||||
$errors['title']['msg'] = '<div class="alert alert-danger"><p id="poll_title_error">' . _('Something is wrong with the format') . '</p></div>';
|
||||
}
|
||||
|
||||
if ($erreur_injection_commentaires) {
|
||||
$errors['description']['aria'] = 'aria-describeby="poll_comment_error" '; $errors['description']['class'] = ' has-error';
|
||||
$errors['description']['msg'] = '<div class="alert alert-danger"><p id="poll_comment_error">' . _("Characters < > and \" are not permitted") . '</p></div>';
|
||||
}
|
||||
if ($error_on_description) {
|
||||
$errors['description']['aria'] = 'aria-describeby="poll_comment_error" ';
|
||||
$errors['description']['class'] = ' has-error';
|
||||
$errors['description']['msg'] = '<div class="alert alert-danger"><p id="poll_comment_error">' . _('Something is wrong with the format') . '</p></div>';
|
||||
}
|
||||
|
||||
if (!$_SESSION["nom"] && Utils::issetAndNoEmpty("poursuivre")) {
|
||||
$errors['name']['aria'] = 'aria-describeby="poll_name_error" '; $errors['name']['class'] = ' has-error';
|
||||
$errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _("Enter a name") . '</p></div>';
|
||||
} elseif ($erreur_injection_nom) {
|
||||
$errors['name']['aria'] = 'aria-describeby="poll_name_error" '; $errors['name']['class'] = ' has-error';
|
||||
$errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _("Characters < > and \" are not permitted") . '</p></div>';
|
||||
}
|
||||
if (empty($_POST['name'])) {
|
||||
$errors['name']['aria'] = 'aria-describeby="poll_name_error" ';
|
||||
$errors['name']['class'] = ' has-error';
|
||||
$errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _('Enter a name') . '</p></div>';
|
||||
} elseif ($error_on_name) {
|
||||
$errors['name']['aria'] = 'aria-describeby="poll_name_error" ';
|
||||
$errors['name']['class'] = ' has-error';
|
||||
$errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _('Something is wrong with the format') . '</p></div>';
|
||||
}
|
||||
|
||||
if (!$_SESSION["adresse"] && Utils::issetAndNoEmpty("poursuivre")) {
|
||||
$errors['email']['aria'] = 'aria-describeby="poll_name_error" '; $errors['email']['class'] = ' has-error';
|
||||
$errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _("Enter an email address") . '</p></div>';
|
||||
} elseif ($erreur_adresse && Utils::issetAndNoEmpty("poursuivre")) {
|
||||
$errors['email']['aria'] = 'aria-describeby="poll_email_error" '; $errors['email']['class'] = ' has-error';
|
||||
$errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _("The address is not correct! You should enter a valid email address (like r.stallman@outlock.com) in order to receive the link to your poll.") . '</p></div>';
|
||||
if (empty($_POST['mail'])) {
|
||||
$errors['email']['aria'] = 'aria-describeby="poll_name_error" ';
|
||||
$errors['email']['class'] = ' has-error';
|
||||
$errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _('Enter an email address') . '</p></div>';
|
||||
} elseif ($error_on_mail) {
|
||||
$errors['email']['aria'] = 'aria-describeby="poll_email_error" ';
|
||||
$errors['email']['class'] = ' has-error';
|
||||
$errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _('The address is not correct! You should enter a valid email address (like r.stallman@outlock.com) in order to receive the link to your poll.') . '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Préparation en fonction des paramètres de session
|
||||
*/
|
||||
|
||||
// REMOTE_USER ?
|
||||
if (USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) {
|
||||
$input_name = '<input type="hidden" name="nom" value="'.$_SESSION["nom"].'" />'.stripslashes($_SESSION["nom"]);
|
||||
} else {
|
||||
$input_name = '<input id="yourname" type="text" name="nom" class="form-control" '.$errors['name']['aria'].' value="'.stripslashes($_SESSION["nom"]).'" />';
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
if (USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) {
|
||||
$input_email = '<input type="hidden" name="adresse" value="'.$_SESSION["adresse"].'">'.$_SESSION["adresse"];
|
||||
$input_name = '<input type="hidden" name="name" value="'.Utils::htmlEscape($_POST['name']).'" />'.$_SESSION['form']->admin_name;
|
||||
$input_email = '<input type="hidden" name="mail" value="'.Utils::htmlEscape($_POST['mail']).'">'.$_SESSION['form']->admin_mail;
|
||||
} else {
|
||||
$input_email = '<input id="email" type="text" name="adresse" class="form-control" '.$errors['email']['aria'].' value="'.$_SESSION["adresse"].'" />';
|
||||
$input_name = '<input id="yourname" type="text" name="name" class="form-control" '.$errors['name']['aria'].' value="'. fromPostOrEmpty('name') .'" />';
|
||||
$input_email = '<input id="email" type="text" name="mail" class="form-control" '.$errors['email']['aria'].' value="'. fromPostOrEmpty('mail') .'" />';
|
||||
}
|
||||
|
||||
// Checkbox checked ?
|
||||
if (!$_SESSION["studsplus"] && !Utils::issetAndNoEmpty('creation_sondage_date') && !Utils::issetAndNoEmpty('creation_sondage_autre')) {
|
||||
$_SESSION["studsplus"]="+";
|
||||
if ($_SESSION['form']->editable) {
|
||||
$editable = 'checked';
|
||||
}
|
||||
|
||||
if ($_SESSION["studsplus"]=="+") {
|
||||
$cocheplus="checked";
|
||||
if ($_SESSION['form']->receiveNewVotes) {
|
||||
$receiveNewVotes = 'checked';
|
||||
}
|
||||
|
||||
if ($_SESSION["mailsonde"]) {
|
||||
$cochemail="checked";
|
||||
if ($_SESSION['form']->receiveNewComments) {
|
||||
$receiveNewComments = 'checked';
|
||||
}
|
||||
|
||||
// Affichage du formulaire
|
||||
// Display form
|
||||
echo '
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2" >
|
||||
<form name="formulaire" id="formulaire" action="' . Utils::get_server_name() . 'infos_sondage.php" method="POST" class="form-horizontal" role="form">
|
||||
|
||||
<div class="alert alert-info">
|
||||
<p>'. _("You are in the poll creation section.").' <br /> '._("Required fields cannot be left blank.") .'</p>
|
||||
<p>'. _('You are in the poll creation section.').' <br /> '._('Required fields cannot be left blank.') .'</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group'.$errors['title']['class'].'">
|
||||
<label for="poll_title" class="col-sm-4 control-label">' . _("Poll title") . ' *</label>
|
||||
<label for="poll_title" class="col-sm-4 control-label">' . _('Poll title') . ' *</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="poll_title" type="text" name="titre" class="form-control" '.$errors['title']['aria'].' value="'.stripslashes($_SESSION["titre"]).'" />
|
||||
<input id="poll_title" type="text" name="title" class="form-control" '.$errors['title']['aria'].' value="'. fromPostOrEmpty('title') .'" />
|
||||
</div>
|
||||
</div>
|
||||
'.$errors['title']['msg'].'
|
||||
<div class="form-group'.$errors['description']['class'].'">
|
||||
<label for="poll_comments" class="col-sm-4 control-label">'. _("Description") .'</label>
|
||||
<label for="poll_comments" class="col-sm-4 control-label">'. _('Description') .'</label>
|
||||
<div class="col-sm-8">
|
||||
<textarea id="poll_comments" name="commentaires" class="form-control" '.$errors['description']['aria'].' rows="5">'.stripslashes($_SESSION["commentaires"]).'</textarea>
|
||||
<textarea id="poll_comments" name="description" class="form-control" '.$errors['description']['aria'].' rows="5">'. fromPostOrEmpty('description') .'</textarea>
|
||||
</div>
|
||||
</div>
|
||||
'.$errors['description']['msg'].'
|
||||
<div class="form-group'.$errors['name']['class'].'">
|
||||
<label for="yourname" class="col-sm-4 control-label">'. _("Your name") .' *</label>
|
||||
<label for="yourname" class="col-sm-4 control-label">'. _('Your name') .' *</label>
|
||||
<div class="col-sm-8">
|
||||
'.$input_name.'
|
||||
</div>
|
||||
</div>
|
||||
'.$errors['name']['msg'];
|
||||
if($config['use_smtp']==true){
|
||||
if ($config['use_smtp']==true) {
|
||||
echo '
|
||||
<div class="form-group'.$errors['email']['class'].'">
|
||||
<label for="email" class="col-sm-4 control-label">'. _("Your email address") .' *<br /><span class="small">'. _("(in the format name@mail.com)") .'</span></label>
|
||||
<label for="email" class="col-sm-4 control-label">'. _('Your email address') .' *<br /><span class="small">'. _('(in the format name@mail.com)') .'</span></label>
|
||||
<div class="col-sm-8">
|
||||
'.$input_email.'
|
||||
</div>
|
||||
@ -263,20 +256,29 @@ if($config['use_smtp']==true){
|
||||
}
|
||||
echo '
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-11">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type=checkbox name=studsplus '.$cocheplus.' id="studsplus">'. _("Voters can modify their vote themselves.") .'
|
||||
<input type=checkbox name="editable" '.$editable.' id="editable">'. _('Voters can modify their vote themselves.') .'
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
if($config['use_smtp']==true){
|
||||
if ($config['use_smtp']==true) {
|
||||
echo '<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-11">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type=checkbox name=mailsonde '.$cochemail.' id="mailsonde">'. _("To receive an email for each new vote.") .'
|
||||
<input type=checkbox name="receiveNewVotes" '.$receiveNewVotes.' id="receiveNewVotes">'. _('To receive an email for each new vote.') .'
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
echo '<div class="form-group">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type=checkbox name="receiveNewComments" '.$receiveNewComments.' id="receiveNewComments">'. _('To receive an email for each new comment.') .'
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -288,7 +290,7 @@ echo '
|
||||
<button name="poursuivre" value="'. $choix_sondage .'" type="submit" class="btn btn-success" title="'. _('Go to step 2') . '">'. _('Next') . '</button>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript"> document.formulaire.titre.focus(); </script>
|
||||
<script type="text/javascript">document.formulaire.title.focus();</script>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,100 +1,112 @@
|
||||
-- Base de données: `opensondage`
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure `poll`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `poll` (
|
||||
`id` CHAR(16) NOT NULL,
|
||||
`admin_id` CHAR(24) NOT NULL,
|
||||
`title` TEXT NOT NULL,
|
||||
`description` TEXT,
|
||||
`admin_name` VARCHAR(64) DEFAULT NULL,
|
||||
`admin_mail` VARCHAR(128) DEFAULT NULL,
|
||||
`creation_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`end_date` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`format` VARCHAR(1) DEFAULT NULL,
|
||||
`editable` TINYINT(1) DEFAULT '0',
|
||||
`receiveNewVotes` TINYINT(1) DEFAULT '0',
|
||||
`active` TINYINT(1) DEFAULT '1',
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `comments`
|
||||
-- Table structure `slot`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `comments` (
|
||||
`id_comment` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`usercomment` text,
|
||||
PRIMARY KEY (`id_comment`),
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE TABLE IF NOT EXISTS `slot` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`title` TEXT,
|
||||
`moments` TEXT,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `sondage`
|
||||
-- Table structure `comment`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sondage` (
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`commentaires` text,
|
||||
`mail_admin` varchar(128) DEFAULT NULL,
|
||||
`nom_admin` varchar(64) DEFAULT NULL,
|
||||
`titre` text,
|
||||
`id_sondage_admin` char(24) DEFAULT NULL,
|
||||
`date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`date_fin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`format` varchar(2) DEFAULT NULL,
|
||||
`mailsonde` tinyint(1) DEFAULT '0',
|
||||
`statut` int(11) NOT NULL DEFAULT '1' COMMENT '1 = actif ; 0 = inactif ; ',
|
||||
UNIQUE KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE TABLE IF NOT EXISTS `comment` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`name` TEXT,
|
||||
`comment` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `sujet_studs`
|
||||
-- Table structure `vote`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sujet_studs` (
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`sujet` text,
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE TABLE IF NOT EXISTS `vote` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`poll_id` CHAR(16) NOT NULL,
|
||||
`name` VARCHAR(64) NOT NULL,
|
||||
`choices` TEXT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `poll_id` (`poll_id`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `user_studs`
|
||||
-- Data for Name: poll; Type: TABLE DATA;
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `user_studs` (
|
||||
`id_users` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`nom` varchar(64) NOT NULL,
|
||||
`id_sondage` char(16) NOT NULL,
|
||||
`reponses` text NOT NULL,
|
||||
PRIMARY KEY (`id_users`),
|
||||
KEY `id_sondage` (`id_sondage`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=160284 ;
|
||||
|
||||
|
||||
|
||||
INSERT INTO `sondage`
|
||||
(`id_sondage`, `commentaires`, `mail_admin`, `nom_admin`,
|
||||
`titre`, `id_sondage_admin`,
|
||||
`date_fin`, `format`)
|
||||
INSERT INTO `poll`
|
||||
(`id`, `description`, `admin_mail`, `admin_name`, `title`, `admin_id`, `end_date`, `format`)
|
||||
VALUES
|
||||
('aqg259dth55iuhwm','Repas de Noel du service','Stephanie@retaillard.com','Stephanie',
|
||||
'Repas de Noel','aqg259dth55iuhwmy9d8jlwk',
|
||||
FROM_UNIXTIME('1627100361'),'D+');
|
||||
('aqg259dth55iuhwm', 'Repas de Noel du service', 'Stephanie@retaillard.com', 'Stephanie', 'Repas de Noel',
|
||||
'aqg259dth55iuhwmy9d8jlwk', FROM_UNIXTIME('1627100361'), 'D');
|
||||
|
||||
--
|
||||
-- Data for Name: sujet_studs; Type: TABLE DATA;
|
||||
-- Data for Name: slot; Type: TABLE DATA;
|
||||
--
|
||||
|
||||
INSERT INTO `sujet_studs` (`id_sondage`, `sujet`) VALUES
|
||||
('aqg259dth55iuhwm','1225839600@12h,1225839600@19h,1226012400@12h,1226012400@19h,1226876400@12h,1226876400@19h,1227049200@12h,1227049200@19h,1227826800@12h,1227826800@19h');
|
||||
INSERT INTO `slot` (`poll_id`, `title`, `moments`) VALUES
|
||||
('aqg259dth55iuhwm', '1225839600', '12h,19h'),
|
||||
('aqg259dth55iuhwm', '1226012400', '12h,19h'),
|
||||
('aqg259dth55iuhwm', '1226876400', '12h,19h'),
|
||||
('aqg259dth55iuhwm', '1227826800', '12h,19h');
|
||||
|
||||
--
|
||||
-- Data for Name: user_studs; Type: TABLE DATA;
|
||||
-- Data for Name: vote; Type: TABLE DATA;
|
||||
--
|
||||
|
||||
INSERT INTO `user_studs` (`nom`, `id_sondage`, `reponses`, `id_users`) VALUES
|
||||
('marcel','aqg259dth55iuhwm','0110111101','933'),
|
||||
('paul','aqg259dth55iuhwm','1011010111','935'),
|
||||
('sophie','aqg259dth55iuhwm','1110110000','945'),
|
||||
('barack','aqg259dth55iuhwm','0110000','948'),
|
||||
('takashi','aqg259dth55iuhwm','0000110100','951'),
|
||||
('albert','aqg259dth55iuhwm','1010110','975'),
|
||||
('alfred','aqg259dth55iuhwm','0110010','1135'),
|
||||
('marcs','aqg259dth55iuhwm','0100001010','1143'),
|
||||
('laure','aqg259dth55iuhwm','0011000','1347'),
|
||||
('benda','aqg259dth55iuhwm','1101101100','1667'),
|
||||
('Albert','aqg259dth55iuhwm','1111110011','1668');
|
||||
INSERT INTO `vote` (`name`, `poll_id`, `choices`) VALUES
|
||||
('marcel', 'aqg259dth55iuhwm', '02202222'),
|
||||
('paul', 'aqg259dth55iuhwm', '20220202'),
|
||||
('sophie', 'aqg259dth55iuhwm', '22202200'),
|
||||
('barack', 'aqg259dth55iuhwm', '02200000'),
|
||||
('takashi', 'aqg259dth55iuhwm', '00002202'),
|
||||
('albert', 'aqg259dth55iuhwm', '20202200'),
|
||||
('alfred', 'aqg259dth55iuhwm', '02200200'),
|
||||
('marcs', 'aqg259dth55iuhwm', '02000020'),
|
||||
('laure', 'aqg259dth55iuhwm', '00220000'),
|
||||
('benda', 'aqg259dth55iuhwm', '22022022'),
|
||||
('albert', 'aqg259dth55iuhwm', '22222200');
|
||||
|
67
js/core.js
67
js/core.js
@ -32,7 +32,6 @@ $(document).ready(function() {
|
||||
|
||||
|
||||
var datepickerfocus = false; // a11y : datepicker not display on focus until there is one click on the button
|
||||
var lastDate = new Date();
|
||||
|
||||
$(document).on('click','.input-group.date .input-group-addon', function() {
|
||||
datepickerfocus = true;
|
||||
@ -40,17 +39,6 @@ $(document).ready(function() {
|
||||
$(this).parent().datepicker(framadatepicker());
|
||||
$(this).parent().datepicker('show');
|
||||
|
||||
// Trick to keep the last datepicker view
|
||||
if ($(this).parent().find('input').val() == '') {
|
||||
$('.input-group.date input').each(function(){
|
||||
if($(this).val()!='') {
|
||||
lastDate = $(this).val();
|
||||
}
|
||||
});
|
||||
$(this).parent().datepicker('setDate', lastDate);
|
||||
$(this).parent().datepicker('setDate', '');
|
||||
}
|
||||
|
||||
// Trick to refresh calendar
|
||||
$('.datepicker-days .prev').trigger('click');
|
||||
$('.datepicker-days .next').trigger('click');
|
||||
@ -60,9 +48,8 @@ $(document).ready(function() {
|
||||
|
||||
$(document).on('focus','.input-group.date input', function() {
|
||||
if(datepickerfocus) {
|
||||
// unfocus and click instead (because we are not in a11y mode anymore)
|
||||
$(this).blur();
|
||||
$(this).parent().find('.input-group-addon').trigger('click');
|
||||
$(this).parent('.input-group.date').datepicker(framadatepicker());
|
||||
$(this).parent('.input-group.date').datepicker('show');
|
||||
}
|
||||
});
|
||||
/**
|
||||
@ -201,17 +188,25 @@ $(document).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
// 1 day filled and you can submit
|
||||
// 1 day and 2 hours or 2 days and you can submit
|
||||
function SubmitDaysAvalaible() {
|
||||
var nb_filled_days = 0;
|
||||
var nb_filled_hours = 0;
|
||||
|
||||
$('#selected-days fieldset legend input').each(function() {
|
||||
if($(this).val()!='') {
|
||||
nb_filled_days++;
|
||||
}
|
||||
});
|
||||
$('#selected-days .hours').each(function() {
|
||||
if($(this).val()!='') {
|
||||
nb_filled_hours++;
|
||||
}
|
||||
});
|
||||
|
||||
if (nb_filled_days>0) {
|
||||
if (nb_filled_days>1) {
|
||||
$('button[name="choixheures"]').removeClass('disabled');
|
||||
} else if (nb_filled_hours>1 && nb_filled_days==1) {
|
||||
$('button[name="choixheures"]').removeClass('disabled');
|
||||
} else {
|
||||
$('button[name="choixheures"]').addClass('disabled');
|
||||
@ -223,8 +218,8 @@ $(document).ready(function() {
|
||||
});
|
||||
SubmitDaysAvalaible();
|
||||
|
||||
// 1 days and you can remove a day or copy hours
|
||||
if($('#selected-days fieldset').length>0) {
|
||||
// 2 days and you can remove a day or copy hours
|
||||
if($('#selected-days fieldset').length>1) {
|
||||
$('#remove-a-day, #copyhours').removeClass('disabled');
|
||||
}
|
||||
|
||||
@ -261,13 +256,13 @@ $(document).ready(function() {
|
||||
$('.choice-field:last').remove();
|
||||
var nb_choices = $('.choice-field').length;
|
||||
$('#choice'+(nb_choices-1)).focus();
|
||||
if (nb_choices == 1) {
|
||||
if (nb_choices == 2) {
|
||||
$('#remove-a-choice').addClass('disabled');
|
||||
};
|
||||
SubmitChoicesAvalaible();
|
||||
});
|
||||
|
||||
// 1 choice filled and you can submit
|
||||
// 2 choices filled and you can submit
|
||||
function SubmitChoicesAvalaible() {
|
||||
var nb_filled_choices = 0;
|
||||
$('.choice-field input').each(function() {
|
||||
@ -275,7 +270,7 @@ $(document).ready(function() {
|
||||
nb_filled_choices++;
|
||||
}
|
||||
});
|
||||
if(nb_filled_choices>0) {
|
||||
if(nb_filled_choices>1) {
|
||||
$('button[name="fin_sondage_autre"]').removeClass('disabled');
|
||||
} else {
|
||||
$('button[name="fin_sondage_autre"]').addClass('disabled');
|
||||
@ -327,6 +322,20 @@ $(document).ready(function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#name-form .btn-edit').on('click', function() {
|
||||
$('#name-form p').hide();
|
||||
$('.js-name').removeClass("hidden");
|
||||
$('.js-name input').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#name-form .btn-cancel').on('click', function() {
|
||||
$('#name-form p').show();
|
||||
$('#name-form .js-name').addClass("hidden");
|
||||
$('#name-form .btn-edit').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#email-form .btn-edit').on('click', function() {
|
||||
$('#email-form p').hide();
|
||||
$('#email-form .js-email').removeClass("hidden");
|
||||
@ -369,6 +378,20 @@ $(document).ready(function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#expiration-form .btn-edit').on('click', function() {
|
||||
$('#expiration-form p').hide();
|
||||
$('.js-expiration').removeClass("hidden");
|
||||
$('.js-expiration input').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#expiration-form .btn-cancel').on('click', function() {
|
||||
$('#expiration-form p').show();
|
||||
$('#expiration-form .js-expiration').addClass("hidden");
|
||||
$('#expiration-form .btn-edit').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Horizontal scroll buttons
|
||||
if($('.results').width() > $('.container').width()) {
|
||||
$('.scroll-buttons').removeClass('hidden');
|
||||
|
Binary file not shown.
@ -66,7 +66,7 @@ msgstr "(Format: name@mail.com)"
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgid "Back to the homepage of "
|
||||
msgid "Back to the homepage of"
|
||||
msgstr "Zurück zur Homepage von "
|
||||
|
||||
msgid "Error!"
|
||||
@ -242,14 +242,14 @@ msgid "Cancel the rules edit"
|
||||
msgstr "Neue Regeln nicht speichern"
|
||||
|
||||
# Help text adminstuds.php
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button "
|
||||
msgstr "Als Administrator der Umfrage, können Sie alle Zeilen der Umfrage über diesen Button ändern "
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button"
|
||||
msgstr "Als Administrator der Umfrage, können Sie alle Zeilen der Umfrage über diesen Button ändern"
|
||||
|
||||
msgid " remove a column or a line with "
|
||||
msgstr " Zeile oder Spalte entfernen mit "
|
||||
msgid "remove a column or a line with"
|
||||
msgstr "Zeile oder Spalte entfernen mit"
|
||||
|
||||
msgid "and add a new column with "
|
||||
msgstr "und neue Spalte hinzufügen mit "
|
||||
msgid "and add a new column with"
|
||||
msgstr "und neue Spalte hinzufügen mit"
|
||||
|
||||
msgid "Finally, you can change the informations of this poll like the title, the comments or your email address."
|
||||
msgstr "Sie können auch die Informationen dieser Umfrage wie Titel, Kommentare oder E-Mail Adresse ändern."
|
||||
@ -431,8 +431,8 @@ msgstr "Weiter zum 2. Schritt"
|
||||
msgid "Enter a title"
|
||||
msgstr "Titel eingeben"
|
||||
|
||||
msgid "Characters < > and \" are not permitted"
|
||||
msgstr "Die Zeichen < > und \" sind nicht erlaubt !"
|
||||
msgid "Something is wrong with the format"
|
||||
msgstr "Something is wrong with the format"
|
||||
|
||||
msgid "Enter an email address"
|
||||
msgstr "Sie müssen eine E-Mail Adresse eingeben"
|
||||
@ -455,7 +455,7 @@ msgstr "Umfragedaten (2 von 3)"
|
||||
msgid "Choose the dates of your poll"
|
||||
msgstr "Wählen Sie Terminmöglichkeiten für Ihre Umfrage"
|
||||
|
||||
msgid "To schedule an event, it's better to propose at least two choices (two hours for one day or two days)."
|
||||
msgid "To schedule an event you need to propose at least two choices (two hours for one day or two days)."
|
||||
msgstr "Um eine Umfrage für einen Termin zu erstellen, müssen Sie mindestens zwei Auswahlmöglichkeiten angeben (zwei verschiedene Zeiten an einem Tag oder zwei Tage)."
|
||||
|
||||
msgid "You can add or remove additionnal days and hours with the buttons"
|
||||
@ -495,7 +495,7 @@ msgstr "Alle Uhrzeiten entfernen"
|
||||
msgid "Poll subjects (2 on 3)"
|
||||
msgstr "Umfragethemen (2 von 3)"
|
||||
|
||||
msgid "To make a generic poll, it's better to propose at least two choices between differents subjects."
|
||||
msgid "To make a generic poll you need to propose at least two choices between differents subjects."
|
||||
msgstr "Um eine allgemeine Umfrage zu erstellen, benötigen Sie mindestens zwei Auswahlmöglichkeiten zwischen verschiedenen Themen."
|
||||
|
||||
msgid "You can add or remove additional choices with the buttons"
|
||||
@ -567,7 +567,7 @@ msgstr "Löschdatum:"
|
||||
msgid "Your poll will be automatically removed after 6 months."
|
||||
msgstr "Ihre Umfrage wird automatisch nach 6 Monaten gelöscht."
|
||||
|
||||
msgid "You can fix another removal date for it."
|
||||
msgid "You can set a closer removal date for it."
|
||||
msgstr "Sie können auch ein anderes Löschdatum festlegen."
|
||||
|
||||
msgid "Removal date (optional)"
|
||||
@ -610,16 +610,54 @@ msgstr "Umfrage ändern"
|
||||
msgid "Logs"
|
||||
msgstr "Verlauf"
|
||||
|
||||
msgid "Summary"
|
||||
msgstr "Zusammenfassung"
|
||||
|
||||
msgid "Success"
|
||||
msgstr "Erfolg"
|
||||
|
||||
msgid "Fail"
|
||||
msgstr "scheitern"
|
||||
|
||||
msgid "Nothing"
|
||||
msgstr "Nichts"
|
||||
|
||||
msgid "Succeeded:"
|
||||
msgstr "Erfolgreich:"
|
||||
|
||||
msgid "Failed:"
|
||||
msgstr "fehlgeschlagen:"
|
||||
|
||||
msgid "Skipped:"
|
||||
msgstr "übersprungene:"
|
||||
|
||||
msgid "Pages:"
|
||||
msgstr "Seiten:"
|
||||
|
||||
########### Mails ###########
|
||||
# Mails studs.php
|
||||
msgid "Poll's participation"
|
||||
msgstr "Beteiligung an der Umfrage"
|
||||
|
||||
msgid ""
|
||||
"has filled a line.\n"
|
||||
"filled a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
" hat eine Zeile ausgefüllt.\n"
|
||||
"hat eine Zeile ausgefüllt.\n"
|
||||
"Sie finden Ihre Umfrage unter dem folgenden Link:"
|
||||
|
||||
msgid ""
|
||||
"updated a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"updated a vote.\n"
|
||||
"Sie finden Ihre Umfrage unter dem folgenden Link:"
|
||||
|
||||
msgid ""
|
||||
"wrote a comment.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"wrote a comment.\n"
|
||||
"Sie finden Ihre Umfrage unter dem folgenden Link:"
|
||||
|
||||
msgid "Thanks for your confidence."
|
||||
|
Binary file not shown.
@ -66,8 +66,8 @@ msgstr "(in the format name@mail.com)"
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid "Back to the homepage of "
|
||||
msgstr "Back to the homepage of "
|
||||
msgid "Back to the homepage of"
|
||||
msgstr "Back to the homepage of"
|
||||
|
||||
msgid "Error!"
|
||||
msgstr "Error!"
|
||||
@ -81,9 +81,6 @@ msgstr "dd/mm/yyyy"
|
||||
msgid "%A, den %e. %B %Y"
|
||||
msgstr "%A, den %e. %B %Y"
|
||||
|
||||
msgid "Expiration's date"
|
||||
msgstr "Expiration's date"
|
||||
|
||||
msgid "days"
|
||||
msgstr "days"
|
||||
|
||||
@ -199,14 +196,23 @@ msgstr "Cancel the title edit"
|
||||
msgid "Initiator of the poll"
|
||||
msgstr "Initiator of the poll"
|
||||
|
||||
msgid "Edit the name"
|
||||
msgstr "Edit the name"
|
||||
|
||||
msgid "Save the new name"
|
||||
msgstr "Save the new name"
|
||||
|
||||
msgid "Cancel the name edit"
|
||||
msgstr "Cancel the name edit"
|
||||
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
msgid "Edit the email adress"
|
||||
msgstr "Edit the email adress"
|
||||
|
||||
msgid "Save the email address "
|
||||
msgstr "Save the email address "
|
||||
msgid "Save the email address"
|
||||
msgstr "Save the email address"
|
||||
|
||||
msgid "Cancel the email address edit"
|
||||
msgstr "Cancel the email address edit"
|
||||
@ -226,6 +232,18 @@ msgstr "Public link of the poll"
|
||||
msgid "Admin link of the poll"
|
||||
msgstr "Admin link of the poll"
|
||||
|
||||
msgid "Expiration's date"
|
||||
msgstr "Expiration's date"
|
||||
|
||||
msgid "Edit the expiration's date"
|
||||
msgstr "Edit the expiration's date"
|
||||
|
||||
msgid "Save the new expiration's date"
|
||||
msgstr "Save the new expiration's date"
|
||||
|
||||
msgid "Cancel the expiration's date edit"
|
||||
msgstr "Cancel the expiration's date edit"
|
||||
|
||||
msgid "Poll rules"
|
||||
msgstr "Poll rules"
|
||||
|
||||
@ -247,15 +265,18 @@ msgstr "Save the new rules"
|
||||
msgid "Cancel the rules edit"
|
||||
msgstr "Cancel the rules edit"
|
||||
|
||||
msgid "The name is invalid."
|
||||
msgstr "Le nom n'est pas valide."
|
||||
|
||||
# Help text adminstuds.php
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button "
|
||||
msgstr "As poll administrator, you can change all the lines of this poll with this button "
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button"
|
||||
msgstr "As poll administrator, you can change all the lines of this poll with this button"
|
||||
|
||||
msgid " remove a column or a line with "
|
||||
msgstr " remove a column or a line with "
|
||||
msgid "remove a column or a line with"
|
||||
msgstr "remove a column or a line with"
|
||||
|
||||
msgid "and add a new column with "
|
||||
msgstr "and add a new column with "
|
||||
msgid "and add a new column with"
|
||||
msgstr "and add a new column with"
|
||||
|
||||
msgid "Finally, you can change the informations of this poll like the title, the comments or your email address."
|
||||
msgstr "Finally, you can change the informations of this poll like the title, the comments or your email address."
|
||||
@ -437,8 +458,8 @@ msgstr "Go to step 2"
|
||||
msgid "Enter a title"
|
||||
msgstr "Enter a title"
|
||||
|
||||
msgid "Characters < > and \" are not permitted"
|
||||
msgstr "Characters < > and \" are not permitted"
|
||||
msgid "Something is wrong with the format"
|
||||
msgstr "Something is wrong with the format"
|
||||
|
||||
msgid "Enter an email address"
|
||||
msgstr "Enter an email address"
|
||||
@ -461,8 +482,8 @@ msgstr "Poll dates (2 on 3)"
|
||||
msgid "Choose the dates of your poll"
|
||||
msgstr "Choose the dates of your poll"
|
||||
|
||||
msgid "To schedule an event, it's better to propose at least two choices (two hours for one day or two days)."
|
||||
msgstr "To schedule an event, it's better to propose at least two choices (two hours for one day or two days)."
|
||||
msgid "To schedule an event you need to propose at least two choices (two hours for one day or two days)."
|
||||
msgstr "To schedule an event you need to propose at least two choices (two hours for one day or two days)."
|
||||
|
||||
msgid "You can add or remove additionnal days and hours with the buttons"
|
||||
msgstr "You can add or remove additionnal days and hours with the buttons"
|
||||
@ -501,8 +522,8 @@ msgstr "Remove all hours"
|
||||
msgid "Poll subjects (2 on 3)"
|
||||
msgstr "Poll subjects (2 on 3)"
|
||||
|
||||
msgid "To make a generic poll, it's better to propose at least two choices between differents subjects."
|
||||
msgstr "To make a generic poll, it's better to propose at least two choices between differents subjects."
|
||||
msgid "To make a generic poll you need to propose at least two choices between differents subjects."
|
||||
msgstr "To make a generic poll you need to propose at least two choices between differents subjects."
|
||||
|
||||
msgid "You can add or remove additional choices with the buttons"
|
||||
msgstr "You can add or remove additional choices with the buttons"
|
||||
@ -576,15 +597,18 @@ msgstr "Removal date:"
|
||||
msgid "Your poll will be automatically removed after"
|
||||
msgstr "Your poll will be automatically removed after"
|
||||
|
||||
msgid "You can fix another removal date for it."
|
||||
msgstr "You can fix another removal date for it."
|
||||
msgid "You can set a closer removal date for it."
|
||||
msgstr "You can set a closer removal date for it."
|
||||
|
||||
msgid "Removal date (optional)"
|
||||
msgstr "Removal date (optional)"
|
||||
|
||||
############# Admin #############
|
||||
msgid "Polls administrator"
|
||||
msgstr "Polls administrator"
|
||||
msgid "Polls"
|
||||
msgstr "Polls"
|
||||
|
||||
msgid "Migration"
|
||||
msgstr "Migration"
|
||||
|
||||
msgid "Confirm removal of the poll "
|
||||
msgstr "Confirm removal of the poll "
|
||||
@ -619,16 +643,54 @@ msgstr "Change the poll"
|
||||
msgid "Logs"
|
||||
msgstr "Logs"
|
||||
|
||||
msgid "Summary"
|
||||
msgstr "Summary"
|
||||
|
||||
msgid "Success"
|
||||
msgstr "Success"
|
||||
|
||||
msgid "Fail"
|
||||
msgstr "Fail"
|
||||
|
||||
msgid "Nothing"
|
||||
msgstr "Nothing"
|
||||
|
||||
msgid "Succeeded:"
|
||||
msgstr "Succeeded:"
|
||||
|
||||
msgid "Failed:"
|
||||
msgstr "Failed:"
|
||||
|
||||
msgid "Skipped:"
|
||||
msgstr "Skipped:"
|
||||
|
||||
msgid "Pages:"
|
||||
msgstr "Pages:"
|
||||
|
||||
########### Mails ###########
|
||||
# Mails studs.php
|
||||
msgid "Poll's participation"
|
||||
msgstr "Poll's participation"
|
||||
|
||||
msgid ""
|
||||
"has filled a line.\n"
|
||||
"filled a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"has filled a line.\n"
|
||||
"filled a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
|
||||
msgid ""
|
||||
"updated a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"updated a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
|
||||
msgid ""
|
||||
"wrote a comment.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"wrote a comment.\n"
|
||||
"You can find your poll at the link"
|
||||
|
||||
msgid "Thanks for your confidence."
|
||||
|
Binary file not shown.
@ -130,7 +130,7 @@ msgstr "Usted no habia llenado la primera pagina dela encuesta"
|
||||
#: choix_autre.php:63
|
||||
#: adminstuds.php:79
|
||||
#: adminstuds.php:1044
|
||||
msgid "Back to the homepage of "
|
||||
msgid "Back to the homepage of"
|
||||
msgstr "Retroceder al inicio de"
|
||||
|
||||
#: choix_date.php:220
|
||||
@ -255,8 +255,8 @@ msgstr "Introducza un título"
|
||||
#: infos_sondage.php:133
|
||||
#: infos_sondage.php:138
|
||||
#: infos_sondage.php:150
|
||||
msgid "Characters < > and \" are not permitted"
|
||||
msgstr "Los caracteres < > y \" no estan autorizados!"
|
||||
msgid "Something is wrong with the format"
|
||||
msgstr "Something is wrong with the format"
|
||||
|
||||
#: infos_sondage.php:136
|
||||
msgid "Comments: "
|
||||
@ -393,12 +393,26 @@ msgstr "Participación a la encuesta"
|
||||
#: studs.php:171
|
||||
#: studs.php:211
|
||||
msgid ""
|
||||
"has filled a line.\n"
|
||||
"filled a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"acaba de llenar una línea.\n"
|
||||
"Usted puede retroceder a su encuesta con el enlace siguiente"
|
||||
|
||||
msgid ""
|
||||
"updated a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"updated a vote.\n"
|
||||
"Usted puede retroceder a su encuesta con el enlace siguiente"
|
||||
|
||||
msgid ""
|
||||
"wrote a comment.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"wrote a comment.\n"
|
||||
"Usted puede retroceder a su encuesta con el enlace siguiente"
|
||||
|
||||
#: studs.php:246
|
||||
#: adminstuds.php:567
|
||||
msgid "Initiator of the poll"
|
||||
@ -526,7 +540,7 @@ msgid "Characters \" < and > are not permitted"
|
||||
msgstr "Los caracteres \" < y > no estan autorizados!"
|
||||
|
||||
#: choix_autre.php:191
|
||||
msgid "Your poll will be automatically removed after 6 months.<br> You can fix another removal date for it."
|
||||
msgid "Your poll will be automatically removed after 6 months.<br> You can set a closer removal date for it."
|
||||
msgstr "Su encuesta será automaticamente borrado dentro de 6 meses.<br> Mientras, usted puede cambiar este fecha aquí."
|
||||
|
||||
#: choix_autre.php:193
|
||||
@ -612,8 +626,8 @@ msgstr ""
|
||||
"Usted puede cambiar su encuesta al enlace siguiente"
|
||||
|
||||
#: adminstuds.php:582
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button : "
|
||||
msgstr "En calidad de administrador, Usted puede cambiar todas la líneas de este encuesta con este botón :"
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button"
|
||||
msgstr "En calidad de administrador, Usted puede cambiar todas la líneas de este encuesta con este botón"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Cambio"
|
||||
|
Binary file not shown.
@ -66,7 +66,7 @@ msgstr "(au format nom@mail.com)"
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid "Back to the homepage of "
|
||||
msgid "Back to the homepage of"
|
||||
msgstr "Retourner à la page d'accueil de"
|
||||
|
||||
msgid "Error!"
|
||||
@ -81,9 +81,6 @@ msgstr "jj/mm/aaaa"
|
||||
msgid "%A, den %e. %B %Y"
|
||||
msgstr "%A %e %B %Y"
|
||||
|
||||
msgid "Expiration's date"
|
||||
msgstr "Date d'expiration"
|
||||
|
||||
msgid "days"
|
||||
msgstr "jours"
|
||||
|
||||
@ -199,13 +196,22 @@ msgstr "Annuler le changement de titre"
|
||||
msgid "Initiator of the poll"
|
||||
msgstr "Auteur du sondage"
|
||||
|
||||
msgid "Edit the name"
|
||||
msgstr "Modification de l'auteur"
|
||||
|
||||
msgid "Save the new name"
|
||||
msgstr "Enregistrer l'auteur"
|
||||
|
||||
msgid "Cancel the name edit"
|
||||
msgstr "Annuler le changement d'auteur"
|
||||
|
||||
msgid "Email"
|
||||
msgstr "Courriel"
|
||||
|
||||
msgid "Edit the email adress"
|
||||
msgstr "Modifier le courriel"
|
||||
|
||||
msgid "Save the email address "
|
||||
msgid "Save the email address"
|
||||
msgstr "Enregistrer le courriel"
|
||||
|
||||
msgid "Cancel the email address edit"
|
||||
@ -226,6 +232,18 @@ msgstr "Lien public du sondage"
|
||||
msgid "Admin link of the poll"
|
||||
msgstr "Lien d'administration du sondage"
|
||||
|
||||
msgid "Expiration's date"
|
||||
msgstr "Date d'expiration"
|
||||
|
||||
msgid "Edit the expiration's date"
|
||||
msgstr "Modifier la date d'expiration"
|
||||
|
||||
msgid "Save the new expiration's date"
|
||||
msgstr "Enregistrer la date d'expiration"
|
||||
|
||||
msgid "Cancel the expiration's date edit"
|
||||
msgstr "Annuler le changement de date d'expiration"
|
||||
|
||||
msgid "Poll rules"
|
||||
msgstr "Permissions du sondage"
|
||||
|
||||
@ -247,15 +265,18 @@ msgstr "Enregistrer les nouvelles permissions"
|
||||
msgid "Cancel the rules edit"
|
||||
msgstr "Annuler le changement de permissions"
|
||||
|
||||
msgid "The name is invalid."
|
||||
msgstr "Le nom n'est pas valide."
|
||||
|
||||
# Help text adminstuds.php
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button "
|
||||
msgstr "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton "
|
||||
msgid "As poll administrator, you can change all the lines of this poll with this button"
|
||||
msgstr "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton"
|
||||
|
||||
msgid " remove a column or a line with "
|
||||
msgstr " effacer une colonne ou une ligne avec "
|
||||
msgid "remove a column or a line with"
|
||||
msgstr "effacer une colonne ou une ligne avec"
|
||||
|
||||
msgid "and add a new column with "
|
||||
msgstr "et si vous avez oublié de saisir un choix, vous pouvez rajouter une colonne en cliquant sur "
|
||||
msgid "and add a new column with"
|
||||
msgstr "et si vous avez oublié de saisir un choix, vous pouvez rajouter une colonne en cliquant sur"
|
||||
|
||||
msgid "Finally, you can change the informations of this poll like the title, the comments or your email address."
|
||||
msgstr "Vous pouvez enfin également modifier les informations relatives à ce sondage comme le titre, les commentaires ou encore votre courriel."
|
||||
@ -437,8 +458,8 @@ msgstr "Aller à l'étape 2"
|
||||
msgid "Enter a title"
|
||||
msgstr "Il faut saisir un titre !"
|
||||
|
||||
msgid "Characters < > and \" are not permitted"
|
||||
msgstr "Les caractères < > et \" ne sont pas autorisés !"
|
||||
msgid "Something is wrong with the format"
|
||||
msgstr "Quelque chose ne va pas avec le format"
|
||||
|
||||
msgid "Enter an email address"
|
||||
msgstr "Il faut saisir une adresse électronique !"
|
||||
@ -461,8 +482,8 @@ msgstr "Choix des dates (2 sur 3)"
|
||||
msgid "Choose the dates of your poll"
|
||||
msgstr "Choisissez les dates de votre sondage"
|
||||
|
||||
msgid "To schedule an event, it's better to propose at least two choices (two hours for one day or two days)."
|
||||
msgstr "Pour créer un sondage spécial dates, il est préférable de proposer au moins deux choix (deux horaires pour une même journée ou deux jours)."
|
||||
msgid "To schedule an event you need to propose at least two choices (two hours for one day or two days)."
|
||||
msgstr "Pour créer un sondage spécial dates vous devez proposer au moins deux choix (deux horaires pour une même journée ou deux jours)."
|
||||
|
||||
msgid "You can add or remove additionnal days and hours with the buttons"
|
||||
msgstr "Vous pouvez ajouter ou supprimer des jours et horaires supplémentaires avec les boutons"
|
||||
@ -501,8 +522,8 @@ msgstr "Effacer tous les horaires"
|
||||
msgid "Poll subjects (2 on 3)"
|
||||
msgstr "Choix des sujets (2 sur 3)"
|
||||
|
||||
msgid "To make a generic poll, it's better to propose at least two choices between differents subjects."
|
||||
msgstr "Pour créer un sondage classique, il est préférable de proposer au moins deux choix différents."
|
||||
msgid "To make a generic poll you need to propose at least two choices between differents subjects."
|
||||
msgstr "Pour créer un sondage classique, vous devez proposer au moins deux choix différents."
|
||||
|
||||
msgid "You can add or remove additional choices with the buttons"
|
||||
msgstr "Vous pouvez ajouter ou supprimer des choix supplémentaires avec les boutons"
|
||||
@ -576,15 +597,18 @@ msgstr "Date de suppression :"
|
||||
msgid "Your poll will be automatically removed after"
|
||||
msgstr "Votre sondage sera automatiquement effacé dans"
|
||||
|
||||
msgid "You can fix another removal date for it."
|
||||
msgstr "Néanmoins vous pouvez décider ci-dessous d'une date plus rapprochée pour la suppression de votre sondage."
|
||||
msgid "You can set a closer removal date for it."
|
||||
msgstr "Vous pouvez décider d'une date de suppression plus proche."
|
||||
|
||||
msgid "Removal date (optional)"
|
||||
msgstr "Date de suppression (facultative)"
|
||||
msgstr "Date de fin (facultative)"
|
||||
|
||||
############# Admin #############
|
||||
msgid "Polls administrator"
|
||||
msgstr "Administrateur de la base"
|
||||
msgid "Polls"
|
||||
msgstr "Sondages"
|
||||
|
||||
msgid "Migration"
|
||||
msgstr "Migration"
|
||||
|
||||
msgid "Confirm removal of the poll "
|
||||
msgstr "Confirmer la suppression du sondage "
|
||||
@ -619,16 +643,54 @@ msgstr "Modifier le sondage"
|
||||
msgid "Logs"
|
||||
msgstr "Historique"
|
||||
|
||||
msgid "Summary"
|
||||
msgstr "Résumé"
|
||||
|
||||
msgid "Success"
|
||||
msgstr "Réussite"
|
||||
|
||||
msgid "Fail"
|
||||
msgstr "Échèc"
|
||||
|
||||
msgid "Nothing"
|
||||
msgstr "Rien"
|
||||
|
||||
msgid "Succeeded:"
|
||||
msgstr "Réussit:"
|
||||
|
||||
msgid "Failed:"
|
||||
msgstr "Échoué:"
|
||||
|
||||
msgid "Skipped:"
|
||||
msgstr "Passé:"
|
||||
|
||||
msgid "Pages:"
|
||||
msgstr "Pages :"
|
||||
|
||||
########### Mails ###########
|
||||
# Mails studs.php
|
||||
msgid "Poll's participation"
|
||||
msgstr "Participation au sondage"
|
||||
|
||||
msgid ""
|
||||
"has filled a line.\n"
|
||||
"filled a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
" vient de remplir une ligne.\n"
|
||||
"vient de voter.\n"
|
||||
"Vous pouvez retrouver votre sondage avec le lien suivant"
|
||||
|
||||
msgid ""
|
||||
"updated a vote.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"vient de mettre à jour un vote.\n"
|
||||
"Vous pouvez retrouver votre sondage avec le lien suivant"
|
||||
|
||||
msgid ""
|
||||
"vient de rédiger un commentaire.\n"
|
||||
"You can find your poll at the link"
|
||||
msgstr ""
|
||||
"wrote a comment.\n"
|
||||
"Vous pouvez retrouver votre sondage avec le lien suivant"
|
||||
|
||||
msgid "Thanks for your confidence."
|
||||
|
790
studs.php
790
studs.php
@ -16,694 +16,192 @@
|
||||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
session_start();
|
||||
|
||||
if (file_exists('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
} else {
|
||||
include_once('bandeaux.php');
|
||||
}
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
// Le fichier studs.php sert a afficher les résultats d'un sondage à un simple utilisateur.
|
||||
// C'est également l'interface pour ajouter une valeur à un sondage deja créé.
|
||||
$numsondage = false;
|
||||
/* Constants */
|
||||
/* --------- */
|
||||
const UPDATE_VOTE = 1;
|
||||
const ADD_VOTE = 2;
|
||||
const ADD_COMMENT = 3;
|
||||
|
||||
//On récupère le numéro de sondage par le lien web.
|
||||
if(Utils::issetAndNoEmpty('sondage', $_GET) === true) {
|
||||
$numsondage = $_GET["sondage"];
|
||||
$_SESSION["numsondage"] = $numsondage;
|
||||
}
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
if(Utils::issetAndNoEmpty('sondage') === true) {
|
||||
$numsondage = $_POST["sondage"];
|
||||
$_SESSION["numsondage"] = $numsondage;
|
||||
} elseif(Utils::issetAndNoEmpty('sondage', $_COOKIE) === true) {
|
||||
$numsondage = $_COOKIE["sondage"];
|
||||
} elseif(Utils::issetAndNoEmpty('numsondage', $_SESSION) === true) {
|
||||
$numsondage = $_SESSION["numsondage"];
|
||||
}
|
||||
$poll_id = null;
|
||||
$poll = null;
|
||||
$message = null;
|
||||
$editingVoteId = 0;
|
||||
|
||||
$dsondage = ($numsondage != false) ? Utils::get_sondage_from_id($numsondage) : false;
|
||||
if (!$dsondage || $dsondage->id_sondage == ''){
|
||||
Utils::print_header( _("Error!"));
|
||||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
bandeau_titre(_("Error!"));
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
|
||||
echo '
|
||||
<div class="alert alert-warning">
|
||||
<h2>' . _("This poll doesn't exist !") . '</h2>
|
||||
<p>' . _('Back to the homepage of ') . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a></p>
|
||||
</div>'."\n";
|
||||
/* Functions */
|
||||
/*-----------*/
|
||||
|
||||
bandeau_pied();
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
//output a CSV and die()
|
||||
if(Utils::issetAndNoEmpty('export', $_GET) && $dsondage !== false) {
|
||||
if($_GET['export'] == 'csv') {
|
||||
require_once('exportcsv.php');
|
||||
/**
|
||||
* Send a notification to the poll admin to notify him about an update.
|
||||
*
|
||||
* @param $poll stdClass The poll
|
||||
* @param $mailService MailService The mail service
|
||||
* @param $name string The name user who triggered the notification
|
||||
* @param $type int cf: Constants on the top of this page
|
||||
*/
|
||||
function sendUpdateNotification($poll, $mailService, $name, $type) {
|
||||
if (!isset($_SESSION['mail_sent'])) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
if ($poll->receiveNewVotes && (!isset($_SESSION['mail_sent'][$poll->id]) || $_SESSION['mail_sent'][$poll->id] !== true)) {
|
||||
|
||||
// quand on ajoute un commentaire utilisateur
|
||||
if(isset($_POST['ajoutcomment'])) {
|
||||
if (isset($_SESSION['nom']) && Utils::issetAndNoEmpty('commentuser') === false) {
|
||||
// Si le nom vient de la session, on le de-htmlentities
|
||||
$comment_user = html_entity_decode($_SESSION['nom'], ENT_QUOTES, 'UTF-8');
|
||||
} elseif(Utils::issetAndNoEmpty('commentuser')) {
|
||||
$comment_user = $_POST["commentuser"];
|
||||
} elseif(isset($_POST["commentuser"])) {
|
||||
$err |= COMMENT_USER_EMPTY;
|
||||
} else {
|
||||
$comment_user = _('anonyme');
|
||||
}
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . _('Poll\'s participation') . ' : ' . $poll->title;
|
||||
|
||||
if(Utils::issetAndNoEmpty('comment') === false) {
|
||||
$err |= COMMENT_EMPTY;
|
||||
}
|
||||
|
||||
if (isset($_POST["comment"]) && !Utils::is_error(COMMENT_EMPTY) && !Utils::is_error(NO_POLL) && !Utils::is_error(COMMENT_USER_EMPTY)) {
|
||||
// protection contre les XSS : htmlentities
|
||||
$comment = htmlentities($_POST['comment'], ENT_QUOTES, 'UTF-8');
|
||||
$comment_user = htmlentities($comment_user, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
// Check for doublons
|
||||
$comment_doublon = false;
|
||||
$req = 'SELECT * FROM comments WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_comment';
|
||||
$sql = $connect->Prepare($req);
|
||||
$comment_user_doublon = $connect->Execute($sql, array($numsondage));
|
||||
if ($comment_user_doublon->RecordCount() != 0) {
|
||||
while ( $dcomment_user_doublon=$comment_user_doublon->FetchNextObject(false)) {
|
||||
if($dcomment_user_doublon->comment == $comment && $dcomment_user_doublon->usercomment == $comment_user) {
|
||||
$comment_doublon = true;
|
||||
};
|
||||
}
|
||||
$message = $name . ' ';
|
||||
switch ($type) {
|
||||
case UPDATE_VOTE:
|
||||
$message .= _('updated a vote.\nYou can find your poll at the link') . " :\n\n";
|
||||
break;
|
||||
case ADD_VOTE:
|
||||
$message .= _('filled a vote.\nYou can find your poll at the link') . " :\n\n";
|
||||
break;
|
||||
case ADD_COMMENT:
|
||||
$message .= _('wrote a comment.\nYou can find your poll at the link') . " :\n\n";
|
||||
break;
|
||||
}
|
||||
$message .= Utils::getUrlSondage($poll->admin_id, true) . "\n\n";
|
||||
$message .= _('Thanks for your confidence.') . "\n" . NOMAPPLICATION;
|
||||
|
||||
if(!$comment_doublon) {
|
||||
$req = 'INSERT INTO comments (id_sondage, comment, usercomment) VALUES ('.
|
||||
$connect->Param('id_sondage').','.
|
||||
$connect->Param('comment').','.
|
||||
$connect->Param('comment_user').')';
|
||||
$sql = $connect->Prepare($req);
|
||||
$mailService->send($poll->admin_mail, $subject, $message);
|
||||
|
||||
$comments = $connect->Execute($sql, array($numsondage, $comment, $comment_user));
|
||||
if ($comments === false) {
|
||||
$err |= COMMENT_INSERT_FAILED;
|
||||
}
|
||||
}
|
||||
$_SESSION['mail_sent'][$poll->id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
// Action quand on clique le bouton participer
|
||||
$sql = 'SELECT * FROM user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users';
|
||||
$sql = $connect->Prepare($sql);
|
||||
$user_studs = $connect->Execute($sql, array($numsondage));
|
||||
|
||||
$nbcolonnes = substr_count($dsondage->sujet, ',') + 1;
|
||||
if (!Utils::is_error(NO_POLL) && (isset($_POST["boutonp"]))) {
|
||||
//Si le nom est bien entré
|
||||
if (Utils::issetAndNoEmpty('nom') === false) {
|
||||
$err |= NAME_EMPTY;
|
||||
}
|
||||
|
||||
if(!Utils::is_error(NAME_EMPTY) && (! ( USE_REMOTE_USER && isset($_SERVER['REMOTE_USER']) ) || $_POST["nom"] == $_SESSION["nom"])) {
|
||||
$nouveauchoix = '';
|
||||
for ($i=0;$i<$nbcolonnes;$i++) {
|
||||
// radio checked 1 = Yes, 2 = Ifneedbe, 0 = No
|
||||
if (isset($_POST["choix$i"])) {
|
||||
switch ($_POST["choix$i"]) {
|
||||
case 1: $nouveauchoix .= "1";break;
|
||||
case 2: $nouveauchoix .= "2";break;
|
||||
default: $nouveauchoix .= "0";break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$nom=substr($_POST["nom"],0,64);
|
||||
|
||||
// protection contre les XSS : htmlentities
|
||||
$nom = htmlentities($nom, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
while($user = $user_studs->FetchNextObject(false)) {
|
||||
if ($nom == $user->nom) {
|
||||
$err |= NAME_TAKEN;
|
||||
}
|
||||
}
|
||||
|
||||
// Ecriture des choix de l'utilisateur dans la base
|
||||
if (!Utils::is_error(NAME_TAKEN) && !Utils::is_error(NAME_EMPTY)) {
|
||||
|
||||
$sql = 'INSERT INTO user_studs (nom,id_sondage,reponses) VALUES ('.
|
||||
$connect->Param('nom').', '.
|
||||
$connect->Param('numsondage').', '.
|
||||
$connect->Param('nouveauchoix').')';
|
||||
$sql = $connect->Prepare($sql);
|
||||
|
||||
// Todo : Il faudrait lever une erreur en cas d'erreur d'insertion
|
||||
$connect->Execute($sql, array($nom, $numsondage, $nouveauchoix));
|
||||
|
||||
if ($dsondage->mailsonde || /* compatibility for non boolean DB */ $dsondage->mailsonde=="yes" || $dsondage->mailsonde=="true") {
|
||||
if($config['use_smtp']==true){
|
||||
Utils::sendEmail( "$dsondage->mail_admin",
|
||||
"[".NOMAPPLICATION."] "._("Poll's participation")." : ".html_entity_decode($dsondage->titre, ENT_QUOTES, 'UTF-8')."",
|
||||
html_entity_decode("\"$nom\" ", ENT_QUOTES, 'UTF-8').
|
||||
_("has filled a line.\nYou can find your poll at the link") . " :\n\n".
|
||||
Utils::getUrlSondage($numsondage) . " \n\n" .
|
||||
_("Thanks for your confidence.") . "\n". NOMAPPLICATION );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$err |= NAME_EMPTY;
|
||||
}
|
||||
if (!empty($_GET['poll'])) {
|
||||
$poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
|
||||
if($err != 0) {
|
||||
Utils::print_header(_("Error!").' - '.$dsondage->titre);
|
||||
bandeau_titre(_("Error!"));
|
||||
|
||||
echo '<div class="alert alert-danger"><ul class="list-unstyled">'."\n";
|
||||
|
||||
if(Utils::is_error(NAME_EMPTY)) {
|
||||
echo '<li>' . _("Enter a name") . "</li>\n";
|
||||
}
|
||||
if(Utils::is_error(NAME_TAKEN)) {
|
||||
echo '<li>' . _("The name you've chosen already exist in this poll!") . "</li>\n";
|
||||
}
|
||||
if(Utils::is_error(COMMENT_EMPTY) || Utils::is_error(COMMENT_USER_EMPTY)) {
|
||||
echo '<li>' . _("Enter a name and a comment!") . "</li>\n";
|
||||
}
|
||||
if(Utils::is_error(COMMENT_INSERT_FAILED) ) {
|
||||
echo '<li>' . _("Failed to insert the comment!") . "</li>\n";
|
||||
}
|
||||
|
||||
echo '</ul></div>';
|
||||
|
||||
} else {
|
||||
Utils::print_header(_('Poll').' - '.$dsondage->titre);
|
||||
bandeau_titre(_('Poll').' - '.$dsondage->titre);
|
||||
if (!$poll) {
|
||||
$smarty->assign('error', _('This poll doesn\'t exist !'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
$title=stripslashes(str_replace("\\","",$dsondage->titre));
|
||||
echo '
|
||||
<div class="jumbotron">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<h3>'.$title.'</h3>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<div class="btn-group pull-right">
|
||||
<button onclick="javascript:print(); return false;" class="btn btn-default"><span class="glyphicon glyphicon-print"></span> ' . _('Print') . '</button>
|
||||
<button onclick="window.location.href=\'' . Utils::get_server_name() . 'exportcsv.php?numsondage=' . $numsondage . '\';return false;" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> ' . _('Export to CSV') . '</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="form-group">
|
||||
<h4 class="control-label">'. _("Initiator of the poll") .'</h4>
|
||||
<p class="form-control-static"> '.stripslashes($dsondage->nom_admin).'</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="public-link"><a class="public-link" href="' . Utils::getUrlSondage($dsondage->id_sondage) . '">'._("Public link of the poll") .' <span class="btn-link glyphicon glyphicon-link"></span></a></label>
|
||||
<input class="form-control" id="public-link" type="text" readonly="readonly" value="' . Utils::getUrlSondage($dsondage->id_sondage) . '" />
|
||||
</div>
|
||||
</div>'."\n";
|
||||
// -------------------------------
|
||||
// A vote is going to be edited
|
||||
// -------------------------------
|
||||
|
||||
//affichage de la description du sondage
|
||||
if ($dsondage->commentaires) {
|
||||
$commentaires = $dsondage->commentaires;
|
||||
$commentaires=nl2br(str_replace("\\","",$commentaires));
|
||||
echo '
|
||||
<div class="form-group col-md-7">
|
||||
<h4 class="control-label">'._("Description") .'</h4><br />
|
||||
<p class="form-control-static well">'. $commentaires .'</p>
|
||||
</div>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
</div>'."\n"; // .jumbotron
|
||||
|
||||
//On récupere les données et les sujets du sondage
|
||||
$nblignes = $user_studs->RecordCount();
|
||||
|
||||
//on teste pour voir si une ligne doit etre modifiée
|
||||
$testmodifier = false;
|
||||
$ligneamodifier = -1;
|
||||
for ($i=0;$i<$nblignes;$i++) {
|
||||
if (isset($_POST["modifierligne$i"])) {
|
||||
$ligneamodifier = $i;
|
||||
}
|
||||
|
||||
//test pour voir si une ligne est a modifier
|
||||
if (isset($_POST['validermodifier'.$i])) {
|
||||
$modifier = $i;
|
||||
$testmodifier = true;
|
||||
}
|
||||
if (!empty($_POST['edit_vote'])) {
|
||||
$editingVoteId = filter_input(INPUT_POST, 'edit_vote', FILTER_VALIDATE_INT);
|
||||
}
|
||||
|
||||
//si le test est valide alors on affiche des checkbox pour entrer de nouvelles valeurs
|
||||
if ($testmodifier) {
|
||||
$nouveauchoix = '';
|
||||
for ($i=0;$i<$nbcolonnes;$i++) {
|
||||
// radio checked 1 = Yes, 2 = Ifneedbe, 0 = No
|
||||
if (isset($_POST["choix$i"])) {
|
||||
switch ($_POST["choix$i"]) {
|
||||
case 1: $nouveauchoix .= "1";break;
|
||||
case 2: $nouveauchoix .= "2";break;
|
||||
default: $nouveauchoix .= "0";break;
|
||||
}
|
||||
}
|
||||
// -------------------------------
|
||||
// Something to save (edit or add)
|
||||
// -------------------------------
|
||||
|
||||
if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
$name = filter_input(INPUT_POST, 'name', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]);
|
||||
$editedVote = filter_input(INPUT_POST, 'save', FILTER_VALIDATE_INT);
|
||||
$choices = $inputService->filterArray($_POST['choices'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => CHOICE_REGEX]]);
|
||||
|
||||
if (empty($editedVote)) {
|
||||
$message = new Message('danger', _('Something is going wrong...'));
|
||||
}
|
||||
if (count($choices) != count($_POST['choices'])) {
|
||||
$message = new Message('danger', _('There is a problem with your choices.'));
|
||||
}
|
||||
|
||||
$compteur=0;
|
||||
while ($data = $user_studs->FetchNextObject(false) ) {
|
||||
//mise a jour des données de l'utilisateur dans la base SQL
|
||||
if ($compteur == $modifier) {
|
||||
$sql = 'UPDATE user_studs SET reponses='.$connect->Param('nouveauchoix').' WHERE nom='.$connect->Param('nom').' AND id_users='.$connect->Param('id_users');
|
||||
$sql = $connect->Prepare($sql);
|
||||
$connect->Execute($sql, array($nouveauchoix, $data->nom, $data->id_users));
|
||||
|
||||
if ($dsondage->mailsonde=="yes") {
|
||||
Utils::sendEmail( "$dsondage->mail_admin", "[".NOMAPPLICATION."] " . _("Poll's participation") . " : ".html_entity_decode($dsondage->titre, ENT_QUOTES, 'UTF-8'), "\"".html_entity_decode($data->nom, ENT_QUOTES, 'UTF-8')."\""."" . _("has filled a line.\nYou can find your poll at the link") . " :\n\n" . Utils::getUrlSondage($numsondage) . " \n\n" . _("Thanks for your confidence.") . "\n".NOMAPPLICATION );
|
||||
}
|
||||
}
|
||||
$compteur++;
|
||||
}
|
||||
}
|
||||
|
||||
//recuperation des utilisateurs du sondage
|
||||
$sql = 'SELECT * FROM user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users';
|
||||
$sql = $connect->Prepare($sql);
|
||||
$user_studs = $connect->Execute($sql, array($numsondage));
|
||||
|
||||
//reformatage des données des sujets du sondage
|
||||
$toutsujet = explode(",",$dsondage->sujet);
|
||||
|
||||
// Table headers
|
||||
$thead = '<thead>';
|
||||
|
||||
// Button in the first td to avoid remove col on "Return" keypress)
|
||||
$border = array(); // bordure pour distinguer les mois
|
||||
$td_headers = array(); // for a11y, headers="M1 D4 H5" on each td
|
||||
$radio_title = array(); // date for
|
||||
|
||||
// Dates poll
|
||||
if ($dsondage->format=="D"||$dsondage->format=="D+"||$dsondage->format=="D-") {
|
||||
|
||||
$tr_months = '<tr><th role="presentation"></th>';
|
||||
$tr_days = '<tr><th role="presentation"></th>';
|
||||
$tr_hours = '<tr><th role="presentation"></th>';
|
||||
|
||||
// Headers
|
||||
$colspan_month = 1;
|
||||
$colspan_day = 1;
|
||||
|
||||
for ($i = 0; $i < count($toutsujet); $i++) {
|
||||
|
||||
// Current date
|
||||
$current = $toutsujet[$i];
|
||||
$horoCur = explode("@",$current); //horoCur[0] = date, horoCur[1] = hour
|
||||
if (isset($toutsujet[$i+1])){
|
||||
$next = $toutsujet[$i+1];
|
||||
$horoNext = explode("@",$next);
|
||||
}
|
||||
|
||||
$border[$i] = false;
|
||||
$radio_title[$i] = strftime($date_format['txt_short'],$horoCur[0]);
|
||||
|
||||
// Months
|
||||
$td_headers[$i] = 'M'.($i+1-$colspan_month);
|
||||
|
||||
if (isset($toutsujet[$i+1]) && strftime("%B", $horoCur[0]) == strftime("%B", $horoNext[0]) && strftime("%Y", $horoCur[0]) == strftime("%Y", $horoNext[0])){
|
||||
$colspan_month++;
|
||||
if ($message == null) {
|
||||
// Update vote
|
||||
$result = $pollService->updateVote($poll_id, $editedVote, $name, $choices);
|
||||
if ($result) {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
sendUpdateNotification($poll, $mailService, $name, UPDATE_VOTE);
|
||||
} else {
|
||||
$border[$i] = true;
|
||||
$tr_months .= '<th colspan="'.$colspan_month.'" class="bg-primary month" id="M'.($i+1-$colspan_month).'">'.strftime("%B",$horoCur[0]).' '.strftime("%Y", $horoCur[0]).'</th>';
|
||||
$colspan_month=1;
|
||||
$message = new Message('danger', _('Update vote failed.'));
|
||||
}
|
||||
}
|
||||
} elseif (isset($_POST['save'])) { // Add a new vote
|
||||
$name = filter_input(INPUT_POST, 'name', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]);
|
||||
$choices = $inputService->filterArray($_POST['choices'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => CHOICE_REGEX]]);
|
||||
|
||||
// Days
|
||||
$td_headers[$i] .= ' D'.($i+1-$colspan_day);
|
||||
if (empty($name)) {
|
||||
$message = new Message('danger', _('Name is incorrect.'));
|
||||
}
|
||||
if (count($choices) != count($_POST['choices'])) {
|
||||
$message = new Message('danger', _('There is a problem with your choices.'));
|
||||
}
|
||||
|
||||
if (isset($toutsujet[$i+1]) && strftime($date_format['txt_day'],$horoCur[0])==strftime($date_format['txt_day'],$horoNext[0])&&strftime("%B",$horoCur[0])==strftime("%B",$horoNext[0])){
|
||||
$colspan_day++;
|
||||
if ($message == null) {
|
||||
// Add vote
|
||||
$result = $pollService->addVote($poll_id, $name, $choices);
|
||||
if ($result) {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
sendUpdateNotification($poll, $mailService, $name, ADD_VOTE);
|
||||
} else {
|
||||
$rbd = ($border[$i]) ? ' rbd' : '';
|
||||
$tr_days .= '<th colspan="'.$colspan_day.'" class="bg-primary day'.$rbd.'" id="D'.($i+1-$colspan_day).'">'.strftime($date_format['txt_day'],$horoCur[0]).'</th>';
|
||||
$colspan_day=1;
|
||||
$message = new Message('danger', _('Update vote failed.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hours
|
||||
$rbd = ($border[$i]) ? ' rbd' : '';
|
||||
if (isset($horoCur[1]) && $horoCur[1] !== '') {
|
||||
$tr_hours .= '<th class="bg-info'.$rbd.'" id="H'.$i.'" title="'.$horoCur[1].'">'.$horoCur[1].'</th>';
|
||||
$radio_title[$i] .= ' - '.$horoCur[1];
|
||||
$td_headers[$i] .= ' H'.$i;
|
||||
// -------------------------------
|
||||
// Add a comment
|
||||
// -------------------------------
|
||||
|
||||
if (isset($_POST['add_comment'])) {
|
||||
$name = filter_input(INPUT_POST, 'name', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]);
|
||||
$comment = strip_tags($_POST['comment']);
|
||||
|
||||
if (empty($name)) {
|
||||
$message = new Message('danger', _('Name is incorrect.'));
|
||||
}
|
||||
|
||||
if ($message == null) {
|
||||
// Add comment
|
||||
$result = $pollService->addComment($poll_id, $name, $comment);
|
||||
if ($result) {
|
||||
$message = new Message('success', _('Comment added.'));
|
||||
sendUpdateNotification($poll, $mailService, $name, ADD_COMMENT);
|
||||
} else {
|
||||
$tr_hours .= '<th class="bg-info'.$rbd.'"></th>';
|
||||
$message = new Message('danger', _('Comment failed.'));
|
||||
}
|
||||
}
|
||||
|
||||
$border[count($border)-1] = false; // suppression de la bordure droite du dernier mois
|
||||
|
||||
$tr_months .= '<th></th></tr>';
|
||||
$tr_days .= '<th></th></tr>';
|
||||
$tr_hours .= '<th></th></tr>';
|
||||
|
||||
$thead = "\n".$tr_months."\n".$tr_days."\n".$tr_hours."\n";
|
||||
|
||||
// Subjects poll
|
||||
} else {
|
||||
$toutsujet=str_replace("@","<br />",$toutsujet);
|
||||
|
||||
$tr_subjects = '<tr><th role="presentation"></th>';
|
||||
|
||||
for ($i = 0; isset($toutsujet[$i]); $i++) {
|
||||
|
||||
$td_headers[$i]='';$radio_title[$i]=''; // init before concatenate
|
||||
|
||||
// Subjects
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$toutsujet[$i],$md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_a); // Markdown [text](href)
|
||||
if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [![alt](src)](href)
|
||||
|
||||
$th_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
$th_subject_html = '<a href="'.$md_a_img[3][0].'"><img src="'.$md_a_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" /></a>';
|
||||
|
||||
} elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { // ![alt](src)
|
||||
|
||||
$th_subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1);
|
||||
$th_subject_html = '<img src="'.$md_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" />';
|
||||
|
||||
} elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href)
|
||||
|
||||
$th_subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1);
|
||||
$th_subject_html = '<a href="'.$md_a[2][0].'">'.$th_subject_text.'</a>';
|
||||
|
||||
} else { // text only
|
||||
|
||||
$th_subject_text = stripslashes($toutsujet[$i]);
|
||||
$th_subject_html = $th_subject_text;
|
||||
|
||||
}
|
||||
$tr_subjects .= '<th class="bg-info" id="S'.$i.'" title="'.$th_subject_text.'">'.$th_subject_html.'</th>';
|
||||
|
||||
$border[$i] = false;
|
||||
$td_headers[$i] .= 'S'.$i;
|
||||
$radio_title[$i] .= $th_subject_text;
|
||||
|
||||
}
|
||||
|
||||
$thead = $tr_subjects.'<th></th></tr>';
|
||||
}
|
||||
|
||||
// Print headers
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::getUrlSondage($dsondage->id_sondage) . '" method="POST">
|
||||
<input type="hidden" name="sondage" value="' . $numsondage . '"/>
|
||||
';
|
||||
if ($dsondage->format=="A-" || $dsondage->format=="D-") {
|
||||
echo '
|
||||
<div class="alert alert-danger">
|
||||
<p>' . _("The administrator locked this poll, votes and comments are frozen, it's not possible to participate anymore.") . '</p>
|
||||
<p aria-hidden="true"><b>' . _('Legend:'). '</b> <span class="glyphicon glyphicon-ok"></span> =' . _('Yes') . ', <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = ' . _('Ifneedbe') . ', <span class="glyphicon glyphicon-ban-circle"></span> = ' . _('No') . '</p>
|
||||
</div>';
|
||||
} else {
|
||||
echo '
|
||||
<div class="alert alert-info">
|
||||
<p>' . _("If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.") . '</p>
|
||||
<p aria-hidden="true"><b>' . _('Legend:'). '</b> <span class="glyphicon glyphicon-ok"></span> =' . _('Yes') . ', <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = ' . _('Ifneedbe') . ', <span class="glyphicon glyphicon-ban-circle"></span> = ' . _('No') . '</p>
|
||||
</div>';
|
||||
}
|
||||
echo'
|
||||
<div class="hidden row scroll-buttons" aria-hidden="true">
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-sm btn-link scroll-left" title="' . _('Scroll to the left') . '">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-link scroll-right" title="' . _('Scroll to the right') . '">
|
||||
<span class="glyphicon glyphicon-chevron-right"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
// Retrieve data
|
||||
$slots = $pollService->allSlotsByPollId($poll_id);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||
|
||||
<h3>'._('Votes of the poll ').'</h3>
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<table class="results">
|
||||
<caption class="sr-only">'._('Votes of the poll ').$title.'</caption>
|
||||
<thead>'. $thead . '</thead>
|
||||
<tbody>';
|
||||
|
||||
// Print poll results
|
||||
// Assign data to template
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('title', _('Poll') . ' - ' . $poll->title);
|
||||
$smarty->assign('expired', $poll->end_date < time());
|
||||
$smarty->assign('deletion_date', $poll->end_date + PURGE_DELAY * 86400);
|
||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||
$smarty->assign('best_choices', $pollService->computeBestChoices($votes));
|
||||
$smarty->assign('comments', $comments);
|
||||
$smarty->assign('editingVoteId', $editingVoteId);
|
||||
$smarty->assign('message', $message);
|
||||
$smarty->assign('admin', false);
|
||||
|
||||
//Usager pré-authentifié dans la liste?
|
||||
$user_mod = false;
|
||||
|
||||
//affichage des resultats actuels
|
||||
$somme[] = 0;
|
||||
$compteur = 0;
|
||||
|
||||
while ($data = $user_studs->FetchNextObject(false)) {
|
||||
|
||||
$ensemblereponses = $data->reponses;
|
||||
|
||||
//affichage du nom
|
||||
$nombase=str_replace("°","'",$data->nom);
|
||||
echo '<tr>
|
||||
<th class="bg-info">'.stripslashes($nombase).'</th>'."\n";
|
||||
|
||||
// ligne d'un usager pré-authentifié
|
||||
$mod_ok = !( USE_REMOTE_USER && isset($_SERVER['REMOTE_USER']) ) || ($nombase == $_SESSION['nom']);
|
||||
$user_mod |= $mod_ok;
|
||||
|
||||
// pour chaque colonne
|
||||
for ($k=0; $k < $nbcolonnes; $k++) {
|
||||
// on remplace les choix de l'utilisateur par une ligne de checkbox pour recuperer de nouvelles valeurs
|
||||
if ($compteur == $ligneamodifier) {
|
||||
|
||||
$car = substr($ensemblereponses, $k , 1);
|
||||
|
||||
// variable pour afficher la valeur cochée
|
||||
$car_html[0]='value="0"';$car_html[1]='value="1"';$car_html[2]='value="2"';
|
||||
switch ($car) {
|
||||
case "1": $car_html[1]='value="1" checked';break;
|
||||
case "2": $car_html[2]='value="2" checked';break;
|
||||
default: $car_html[0]='value="0" checked';break;
|
||||
}
|
||||
|
||||
echo '
|
||||
<td class="bg-info" headers="'.$td_headers[$k ].'">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-'.$k.'" name="choix'.$k.'" '.$car_html[1].' />
|
||||
<label class="btn btn-default btn-xs" for="y-choice-'.$k.'" title="' . _('Vote "yes" for ') . $radio_title[$k] . '">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">' . _('Yes') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-'.$k.'" name="choix'.$k.'" '.$car_html[2].' />
|
||||
<label class="btn btn-default btn-xs" for="i-choice-'.$k.'" title="' . _('Vote "ifneedbe" for ') . $radio_title[$k] . '">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">' . _('Ifneedbe') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-'.$k.'" name="choix'.$k.'" '.$car_html[0].'/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-'.$k.'" title="' . _('Vote "no" for ') . $radio_title[$k] . '">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">' . _('No') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>'."\n";
|
||||
|
||||
} else {
|
||||
$rbd = ($border[$k]) ? ' rbd' : '';
|
||||
$car = substr($ensemblereponses, $k, 1);
|
||||
switch ($car) {
|
||||
case "1": echo '<td class="bg-success text-success'.$rbd.'" headers="'.$td_headers[$k].'"><span class="glyphicon glyphicon-ok"></span><span class="sr-only"> ' . _('Yes') . '</span></td>'."\n";
|
||||
if (isset($somme[$k]) === false) {
|
||||
$somme[$k] = 0;
|
||||
}
|
||||
$somme[$k]++; break;
|
||||
case "2": echo '<td class="bg-warning text-warning'.$rbd.'" headers="'.$td_headers[$k].'">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only"> ' . _('Yes') . _(', ifneedbe') . '</span></td>'."\n"; break;
|
||||
default: echo '<td class="bg-danger'.$rbd.'" headers="'.$td_headers[$k].'"><span class="sr-only">' . _('No') . '</span></td>'."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//a la fin de chaque ligne se trouve les boutons modifier
|
||||
if ($compteur != $ligneamodifier && ($dsondage->format=="A+"||$dsondage->format=="D+") && $mod_ok) {
|
||||
echo '
|
||||
<td>
|
||||
<button type="submit" class="btn btn-link btn-sm" name="modifierligne'.$compteur.'" title="'. _('Edit the line:') .' '.stripslashes($nombase).'">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _('Edit') . '</span>
|
||||
</button>
|
||||
</td>'."\n";
|
||||
}
|
||||
|
||||
//demande de confirmation pour modification de ligne
|
||||
for ($i=0;$i<$nblignes;$i++) {
|
||||
if (isset($_POST["modifierligne$i"])) {
|
||||
if ($compteur == $i) {
|
||||
echo '<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="validermodifier'.$compteur.'" title="'. _('Save the choices') .' '.stripslashes($nombase).'">'. _('Save') .'</button></td>'."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compteur++;
|
||||
echo '</tr>'."\n";
|
||||
}
|
||||
|
||||
// affichage de la ligne pour un nouvel utilisateur
|
||||
if (( !(USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) || !$user_mod) && $ligneamodifier==-1 && ($dsondage->format!="A-" && $dsondage->format!="D-")) {
|
||||
//affichage de la case vide de texte pour un nouvel utilisateur
|
||||
echo '<tr id="vote-form">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="text" id="nom" name="nom" class="form-control" title="'. _('Your name') .'" placeholder="'. _('Your name') .'" />
|
||||
</div>
|
||||
</td>'."\n";
|
||||
|
||||
//une ligne de checkbox pour le choix du nouvel utilisateur
|
||||
for ($i = 0; $i < $nbcolonnes; $i++) {
|
||||
echo '
|
||||
<td class="bg-info" headers="'.$td_headers[$i].'">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-'.$i.'" name="choix'.$i.'" value="1" />
|
||||
<label class="btn btn-default btn-xs" for="y-choice-'.$i.'" title="' . _('Vote "yes" for ') . $radio_title[$i] . '">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">' . _('Yes') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-'.$i.'" name="choix'.$i.'" value="2" />
|
||||
<label class="btn btn-default btn-xs" for="i-choice-'.$i.'" title="' . _('Vote "ifneedbe" for ') . $radio_title[$i] . '">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">' . _('Ifneedbe') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-'.$i.'" name="choix'.$i.'" value="0" checked/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-'.$i.'" title="' . _('Vote "no" for ') . $radio_title[$i] . '">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">' . _('No') . '</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>'."\n";
|
||||
}
|
||||
|
||||
// Affichage du bouton de formulaire pour inscrire un nouvel utilisateur dans la base
|
||||
echo '<td><button type="submit" class="btn btn-success btn-sm" name="boutonp" title="'. _('Save the choices') .'">'. _('Save') .'</button></td>
|
||||
</tr>'."\n";
|
||||
|
||||
}
|
||||
|
||||
// Addition and Best choice
|
||||
//affichage de la ligne contenant les sommes de chaque colonne
|
||||
$tr_addition = '<tr id="addition"><td>'. _("Addition") .'</td>';
|
||||
$meilleurecolonne = max($somme);
|
||||
$compteursujet = 0;
|
||||
$meilleursujet = '<ul style="list-style:none">';
|
||||
for ($i = 0; $i < $nbcolonnes; $i++) {
|
||||
if (isset($somme[$i]) && $somme[$i] > 0 ) {
|
||||
if (in_array($i, array_keys($somme, max($somme)))){
|
||||
|
||||
$tr_addition .= '<td><span class="glyphicon glyphicon-star text-warning"></span><span>'.$somme[$i].'</span></td>';
|
||||
|
||||
$meilleursujet.= '<li><b>'.$radio_title[$i].'</b></li>';
|
||||
$compteursujet++;
|
||||
|
||||
} else {
|
||||
$tr_addition .= '<td>'.$somme[$i].'</td>';
|
||||
}
|
||||
} else {
|
||||
$tr_addition .= '<td></td>';
|
||||
}
|
||||
}
|
||||
$tr_addition .= '<td></td></tr>';
|
||||
|
||||
$meilleursujet = str_replace("°", "'", $meilleursujet).'</ul>';
|
||||
$vote_str = ($meilleurecolonne > 1) ? $vote_str = _('votes') : _('vote');
|
||||
|
||||
// Print Addition and Best choice
|
||||
echo $tr_addition.'
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">'."\n";
|
||||
|
||||
if ($compteursujet == 1) {
|
||||
echo '
|
||||
<div class="col-sm-12"><h3>' . _("Best choice") . '</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The best choice at this time is:") . '</p>
|
||||
' . $meilleursujet . '
|
||||
<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p>
|
||||
</div>'."\n";
|
||||
} elseif ($compteursujet > 1) {
|
||||
echo '
|
||||
<div class="col-sm-12"><h3>' . _("Best choices") . '</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The bests choices at this time are:") . '</p>
|
||||
' . $meilleursujet . '
|
||||
<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p>
|
||||
</div>'."\n";
|
||||
}
|
||||
|
||||
echo '
|
||||
</div>
|
||||
<hr role="presentation" />';
|
||||
|
||||
// Comments
|
||||
$sql = 'select * from comments where id_sondage='.$connect->Param('numsondage').' order by id_comment';
|
||||
$sql = $connect->Prepare($sql);
|
||||
$comment_user=$connect->Execute($sql, array($numsondage));
|
||||
|
||||
if ($comment_user->RecordCount() != 0) {
|
||||
echo '<div><h3>' . _("Comments of polled people") . '</h3>'."\n";
|
||||
|
||||
while($dcomment = $comment_user->FetchNextObject(false)) {
|
||||
echo '
|
||||
<div class="comment">
|
||||
<b>'.stripslashes($dcomment->usercomment). ' :</b>
|
||||
<span class="comment">' . stripslashes(nl2br($dcomment->comment)) . '</span>
|
||||
</div>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
if ($dsondage->format!="A-" && $dsondage->format!="D-") {
|
||||
echo '
|
||||
<div class="hidden-print alert alert-info">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<fieldset id="add-comment"><legend>' . _("Add a comment in the poll") . '</legend>
|
||||
<div class="form-group">
|
||||
<p><label for="commentuser">'. _("Your name") .'</label><input type=text class="form-control" name="commentuser" id="commentuser" /></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<p><label for="comment">'. _("Your comment") .'</label><br />
|
||||
<textarea name="comment" id="comment" class="form-control" rows="2" cols="40"></textarea></p>
|
||||
</div>
|
||||
<p class="text-center"><input type="submit" name="ajoutcomment" value="'. _("Send the comment") .'" class="btn btn-success"></p>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
echo '
|
||||
</form>';
|
||||
|
||||
bandeau_pied();
|
||||
$smarty->display('studs.tpl');
|
||||
|
39
tpl/add_slot.tpl
Normal file
39
tpl/add_slot.tpl
Normal file
@ -0,0 +1,39 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true}" method="POST">
|
||||
<div class="alert alert-info text-center">
|
||||
<h2>{_('Column\'s adding')}</h2>
|
||||
|
||||
{if $format === 'D'}
|
||||
<div class="form-group">
|
||||
<label for="newdate" class="col-md-4">{_('Day')}</label>
|
||||
<div class="col-md-8">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
|
||||
<input type="text" id="newdate" data-date-format="{_('dd/mm/yyyy')}" aria-describedby="dateformat" name="newdate" class="form-control" placeholder="{_('dd/mm/yyyy')}" />
|
||||
</div>
|
||||
<span id="dateformat" class="sr-only">{_('(dd/mm/yyyy)')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newmoment" class="col-md-4">{_('Time')}</label>
|
||||
<div class="col-md-8">
|
||||
<input type="text" id="newmoment" name="newmoment" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<div class="form-group">
|
||||
<label for="choice" class="col-md-4">{_('Choice')}</label>
|
||||
<div class="col-md-8">
|
||||
<input type="text" id="choice" name="choice" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group">
|
||||
<button class="btn btn-default" type="submit" name="back">{_('Back to the poll')}</button>
|
||||
<button type="submit" name="confirm_add_slot" class="btn btn-success">{_('Add a column')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
10
tpl/admin/admin_page.tpl
Normal file
10
tpl/admin/admin_page.tpl
Normal file
@ -0,0 +1,10 @@
|
||||
{extends 'page.tpl'}
|
||||
|
||||
{block 'main'}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<a href="{'admin'|resource}">{_('Back to administration')}</a>
|
||||
</div>
|
||||
</div>
|
||||
{block 'admin_main'}{/block}
|
||||
{/block}
|
20
tpl/admin/index.tpl
Normal file
20
tpl/admin/index.tpl
Normal file
@ -0,0 +1,20 @@
|
||||
{extends 'admin/admin_page.tpl'}
|
||||
|
||||
{block 'main'}
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-xs-12">
|
||||
<a href="./polls.php"><h2>{_('Polls')}</h2></a>
|
||||
</div>
|
||||
<div class="col-md-6 col-xs-12">
|
||||
<a href="./migration.php"><h2>{_('Migration')}</h2></a>
|
||||
</div>
|
||||
<div class="col-md-6 col-xs-12">
|
||||
<a href="./purge.php"><h2>{_('Purge')}</h2></a>
|
||||
</div>
|
||||
{if $logsAreReadable}
|
||||
<div class="col-md-6 col-xs-12">
|
||||
<a href="./logs.php"><h2>{_('Logs')}</h2></a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
5
tpl/admin/logs.tpl
Normal file
5
tpl/admin/logs.tpl
Normal file
@ -0,0 +1,5 @@
|
||||
{extends 'admin/admin_page.tpl'}
|
||||
|
||||
{block 'admin_main'}
|
||||
<pre>{$logs|html}</pre>
|
||||
{/block}
|
39
tpl/admin/migration.tpl
Normal file
39
tpl/admin/migration.tpl
Normal file
@ -0,0 +1,39 @@
|
||||
{extends 'admin/admin_page.tpl'}
|
||||
|
||||
{block 'admin_main'}
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h2>{_('Summary')}</h2>
|
||||
{_('Succeeded:')} <span class="label label-warning">{$countSucceeded|html} / {$countTotal|html}</span>
|
||||
<br/>
|
||||
{_('Failed:')} <span class="label label-danger">{$countFailed|html} / {$countTotal|html}</span>
|
||||
<br/>
|
||||
{_('Skipped:')} <span class="label label-info">{$countSkipped|html} / {$countTotal|html}</span>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h2>{_('Success')}</h2>
|
||||
<ul>
|
||||
{foreach $success as $s}
|
||||
<li>{$s|html}</li>
|
||||
{foreachelse}
|
||||
<li>{_('Nothing')}</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h2>{_('Fail')}</h2>
|
||||
<ul>
|
||||
{foreach $fail as $f}
|
||||
<li>{$f|html}</li>
|
||||
{foreachelse}
|
||||
<li>{_('Nothing')}</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 well well-sm">
|
||||
{_('Page generated in')} {$time} {_('secondes')}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
75
tpl/admin/polls.tpl
Normal file
75
tpl/admin/polls.tpl
Normal file
@ -0,0 +1,75 @@
|
||||
{extends 'admin/admin_page.tpl'}
|
||||
|
||||
{block 'admin_main'}
|
||||
<form action="" method="POST">
|
||||
<input type="hidden" name="csrf" value="{$crsf}"/>
|
||||
{if $poll_to_delete}
|
||||
<div class="alert alert-warning text-center">
|
||||
<h3>{_("Confirm removal of the poll ")}"{$poll_to_delete->id|html}"</h3>
|
||||
|
||||
<p>
|
||||
<button class="btn btn-default" type="submit" value="1"
|
||||
name="annullesuppression">{_('Keep this poll!')}</button>
|
||||
<button type="submit" name="delete_confirm" value="{$poll_to_delete->id|html}"
|
||||
class="btn btn-danger">{_('Remove this poll!')}</button>
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{$polls|count} / {$count} {_('polls in the database at this time')}
|
||||
</div>
|
||||
|
||||
|
||||
<table class="table table-bordered table-polls">
|
||||
<tr align="center">
|
||||
<th scope="col"></th>
|
||||
<th scope="col">{_('Title')}</th>
|
||||
<th scope="col">{_('Author')}</th>
|
||||
<th scope="col">{_('Email')}</th>
|
||||
<th scope="col">{_('Expiration\'s date')}</th>
|
||||
<th scope="col">{_('Users')}</th>
|
||||
<th scope="col">{_('Poll ID')}</th>
|
||||
<th scope="col" colspan="3">{_('Actions')}</th>
|
||||
</tr>
|
||||
{foreach $polls as $poll}
|
||||
<tr align="center">
|
||||
<td class="cell-format">
|
||||
{if $poll->format === 'D'}
|
||||
<span class="glyphicon glyphicon-calendar" aria-hidden="true" title="{_('Date')}"></span><span class="sr-only">{_('Date')}</span>
|
||||
{else}
|
||||
<span class="glyphicon glyphicon-list-alt" aria-hidden="true" title="{_('Classic')}"></span><span class="sr-only">{_('Classic')}</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$poll->title|html}</td>
|
||||
<td>{$poll->admin_name|html}</td>
|
||||
<td>{$poll->admin_mail|html}</td>
|
||||
|
||||
{if strtotime($poll->end_date) > time()}
|
||||
<td>{date('d/m/y', strtotime($poll->end_date))}</td>
|
||||
{else}
|
||||
<td><span class="text-danger">{strtotime($poll->end_date)|date_format:'d/m/Y'}</span></td>
|
||||
{/if}
|
||||
<td>{$poll->votes|html}</td>
|
||||
<td>{$poll->id|html}</td>
|
||||
<td><a href="{$poll->id|poll_url|html}" class="btn btn-link" title="{_('See the poll')}"><span class="glyphicon glyphicon-eye-open"></span><span class="sr-only">{_('See the poll')}</span></a></td>
|
||||
<td><a href="{$poll->admin_id|poll_url:true|html}" class="btn btn-link" title="{_('Change the poll')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Change the poll')}</span></a></td>
|
||||
<td><button type="submit" name="delete_poll" value="{$poll->id|html}" class="btn btn-link" title="{_('Remove the poll')}"><span class="glyphicon glyphicon-trash text-danger"></span><span class="sr-only">{_('Remove the poll')}</span></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
|
||||
<div class="panel-heading">
|
||||
{_('Pages:')}
|
||||
{for $p=1 to $pages}
|
||||
{if $p===$page}
|
||||
<a href="{$SERVER_URL}{$SCRIPT_NAME}?page={$p}" class="btn btn-danger" disabled="disabled">{$p}</a>
|
||||
{else}
|
||||
<a href="{$SERVER_URL}{$SCRIPT_NAME}?page={$p}" class="btn btn-info">{$p}</a>
|
||||
{/if}
|
||||
{/for}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
13
tpl/admin/purge.tpl
Normal file
13
tpl/admin/purge.tpl
Normal file
@ -0,0 +1,13 @@
|
||||
{extends 'admin/admin_page.tpl'}
|
||||
|
||||
{block 'admin_main'}
|
||||
{if $message}
|
||||
<div class="alert alert-dismissible alert-info" role="alert">{$message|html}<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>
|
||||
{/if}
|
||||
<form action="" method="POST">
|
||||
<input type="hidden" name="csrf" value="{$crsf}"/>
|
||||
<div class="text-center">
|
||||
<button type="submit" name="action" value="purge" class="btn btn-warning">{_('Purge all polls')} <span class="glyphicon glyphicon-trash text-danger"></span><span class="sr-only">{_('Purge all polls')}</span></button>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
11
tpl/confirm/delete_comments.tpl
Normal file
11
tpl/confirm/delete_comments.tpl
Normal file
@ -0,0 +1,11 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{_('Confirm removal of all comments of the poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{_('Keep comments')}</button>
|
||||
<button type="submit" name="confirm_remove_all_comments" class="btn btn-danger">{_('Remove all comments!')}</button></p>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
11
tpl/confirm/delete_poll.tpl
Normal file
11
tpl/confirm/delete_poll.tpl
Normal file
@ -0,0 +1,11 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{_('Confirm removal of your poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{_('Keep this poll')}</button>
|
||||
<button type="submit" name="confirm_delete_poll" class="btn btn-danger">{_('Remove this poll!')}</button></p>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
11
tpl/confirm/delete_votes.tpl
Normal file
11
tpl/confirm/delete_votes.tpl
Normal file
@ -0,0 +1,11 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{_('Confirm removal of all votes of the poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{_('Keep votes')}</button>
|
||||
<button type="submit" name="confirm_remove_all_votes" class="btn btn-danger">{_('Remove all votes!')}</button></p>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
8
tpl/error.tpl
Normal file
8
tpl/error.tpl
Normal file
@ -0,0 +1,8 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<div class="alert alert-warning">
|
||||
<h2>{$error|html}</h2>
|
||||
<p>{_('Back to the homepage of')} <a href="{$SERVER_URL|html}">{$APPLICATION_NAME|html}</a></p>
|
||||
</div>
|
||||
{/block}
|
4
tpl/footer.tpl
Normal file
4
tpl/footer.tpl
Normal file
@ -0,0 +1,4 @@
|
||||
</main>
|
||||
</div> <!-- .container -->
|
||||
</body>
|
||||
</html>
|
29
tpl/head.tpl
Normal file
29
tpl/head.tpl
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{$html_lang}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
{if !empty($title)}
|
||||
<title>{$title|html} - {$APPLICATION_NAME|html}</title>
|
||||
{else}
|
||||
<title>{$APPLICATION_NAME|html}</title>
|
||||
{/if}
|
||||
|
||||
<link rel="stylesheet" href="{'css/bootstrap.min.css'|resource}">
|
||||
<link rel="stylesheet" href="{'css/datepicker3.css'|resource}">
|
||||
<link rel="stylesheet" href="{'css/style.css'|resource}">
|
||||
<link rel="stylesheet" href="{'css/frama.css'|resource}">
|
||||
<link rel="stylesheet" href="{'css/print.css'|resource}" media="print">
|
||||
<script type="text/javascript" src="{'js/jquery-1.11.1.min.js'|resource}"></script>
|
||||
<script type="text/javascript" src="{'js/bootstrap.min.js'|resource}"></script>
|
||||
<script type="text/javascript" src="{'js/bootstrap-datepicker.js'|resource}"></script>
|
||||
<script type="text/javascript" src="{"js/locales/bootstrap-datepicker.$html_lang.js"|resource}"></script>
|
||||
<script type="text/javascript" src="{'js/core.js'|resource}"></script>
|
||||
|
||||
{if !empty($nav_js)}
|
||||
<script src="{'nav/nav.js'|resource}" id="nav_js" type="text/javascript" charset="utf-8"></script><!-- /Framanav -->
|
||||
{/if}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container ombre">
|
21
tpl/header.tpl
Normal file
21
tpl/header.tpl
Normal file
@ -0,0 +1,21 @@
|
||||
<header role="banner">
|
||||
{if count($langs)>1}
|
||||
<form method="post" action="" class="hidden-print">
|
||||
<div class="input-group input-group-sm pull-right col-md-2 col-xs-4">
|
||||
<select name="lang" class="form-control" title="{_("Select the language")}" >
|
||||
{foreach $langs as $lang_key=>$lang_value}
|
||||
<option lang="{substr($lang_key, 0, 2)}" {if substr($lang_key, 0, 2)==$html_lang}selected{/if} value="{$lang_key|html}">{$lang_value|html}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default btn-sm" title="{_("Change the language")}">OK</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
<h1><a href="{$SERVER_URL|html}" title="{_("Home")} - {$APPLICATION_NAME|html}"><img src="{$TITLE_IMAGE|resource}" alt="{$APPLICATION_NAME|html}"/></a></h1>
|
||||
{if !empty($title)}<h2 class="lead"><i>{$title|html}</i></h2>{/if}
|
||||
<hr class="trait" role="presentation" />
|
||||
</header>
|
||||
<main role="main">
|
6
tpl/page.tpl
Normal file
6
tpl/page.tpl
Normal file
@ -0,0 +1,6 @@
|
||||
{include file='head.tpl'}
|
||||
{include file='header.tpl'}
|
||||
|
||||
{block name=main}{/block}
|
||||
|
||||
{include file='footer.tpl'}
|
40
tpl/part/comments.tpl
Normal file
40
tpl/part/comments.tpl
Normal file
@ -0,0 +1,40 @@
|
||||
<hr role="presentation" id="comments" class="hidden-print"/>
|
||||
<form action="#comments" method="POST">
|
||||
|
||||
{* Comment list *}
|
||||
|
||||
{if $comments|count > 0}
|
||||
<h3>{_("Comments of polled people")}</h3>
|
||||
{foreach $comments as $comment}
|
||||
<div class="comment">
|
||||
{if $admin && !$expired}
|
||||
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{_('Remove the comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span></button>
|
||||
{/if}
|
||||
<b>{$comment->name|html}</b>
|
||||
<span class="comment">{nl2br($comment->comment|html)}</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
|
||||
{* Add comment form *}
|
||||
{if $active && !$expired}
|
||||
<div class="hidden-print alert alert-info">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<fieldset id="add-comment"><legend>{_("Add a comment to the poll")}</legend>
|
||||
<div class="form-group">
|
||||
<label for="name" class="control-label">{_("Your name")}</label>
|
||||
<input type="text" name="name" id="name" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="comment" class="control-label">{_("Your comment")}</label>
|
||||
<textarea name="comment" id="comment" class="form-control" rows="2" cols="40"></textarea>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<input type="submit" name="add_comment" value="{_("Send the comment")}" class="btn btn-success">
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{/if}
|
||||
</form>
|
11
tpl/part/poll_hint.tpl
Normal file
11
tpl/part/poll_hint.tpl
Normal file
@ -0,0 +1,11 @@
|
||||
{if $active}
|
||||
<div class="alert alert-info">
|
||||
<p>{_("If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.")}</p>
|
||||
<p aria-hidden="true"><b>{_('Legend:')}</b> <span class="glyphicon glyphicon-ok"></span> = {_('Yes')}, <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = {_('Ifneedbe')}, <span class="glyphicon glyphicon-ban-circle"></span> = {_('No')}</p>
|
||||
</div>
|
||||
{else}
|
||||
<div class="alert alert-danger">
|
||||
<p>{_("The administrator locked this poll, votes and comments are frozen, it's not possible to participate anymore.")}</p>
|
||||
<p aria-hidden="true"><b>{_('Legend:')}</b> <span class="glyphicon glyphicon-ok"></span> = {_('Yes')}, <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = {_('Ifneedbe')}, <span class="glyphicon glyphicon-ban-circle"></span> = {_('No')}</p>
|
||||
</div>
|
||||
{/if}
|
7
tpl/part/poll_hint_admin.tpl
Normal file
7
tpl/part/poll_hint_admin.tpl
Normal file
@ -0,0 +1,7 @@
|
||||
<div class="alert alert-info">
|
||||
<p>{_('As poll administrator, you can change all the lines of this poll with this button')} <span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span>,
|
||||
{_('remove a column or a line with')} <span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span>
|
||||
{_('and add a new column with')} <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">{_('Add a column')}</span>.</p>
|
||||
<p>{_('Finally, you can change the informations of this poll like the title, the comments or your email address.')}</p>
|
||||
<p aria-hidden="true"><strong>{_('Legend:')}</strong> <span class="glyphicon glyphicon-ok"></span> = {_('Yes')}, <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = {_('Ifneedbe')}, <span class="glyphicon glyphicon-ban-circle"></span> = {_('No')}</p>
|
||||
</div>
|
160
tpl/part/poll_info.tpl
Normal file
160
tpl/part/poll_info.tpl
Normal file
@ -0,0 +1,160 @@
|
||||
{$admin = $admin|default:false}
|
||||
|
||||
{if $admin}<form action="{$admin_poll_id|poll_url:true}" method="POST">{/if}
|
||||
<div class="jumbotron{if $admin} bg-danger{/if}">
|
||||
<div class="row">
|
||||
<div id="title-form" class="col-md-7">
|
||||
<h3>{$poll->title|html}{if $admin && !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the title')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</h3>
|
||||
{if $admin && !$expired}
|
||||
<div class="hidden js-title">
|
||||
<label class="sr-only" for="newtitle">{_('Title')}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="newtitle" name="title" size="40" value="{$poll->title|html}" />
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-success" name="update_poll_info" value="title" title="{_('Save the new title')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{_('Cancel the title edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="col-md-5 hidden-print">
|
||||
<div class="btn-group pull-right">
|
||||
<button onclick="print(); return false;" class="btn btn-default"><span class="glyphicon glyphicon-print"></span> {_('Print')}</button>
|
||||
<a href="{$SERVER_URL|html}exportcsv.php?poll={$poll_id|html}" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> {_('Export to CSV')}</a>
|
||||
{if $admin && !$expired}
|
||||
<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-trash"></span> <span class="sr-only">{_("Remove")}</span> <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><button class="btn btn-link" type="submit" name="remove_all_votes">{_('Remove all the votes') }</button></li>
|
||||
<li><button class="btn btn-link" type="submit" name="remove_all_comments">{_('Remove all the comments')}</button></li>
|
||||
<li class="divider" role="presentation"></li>
|
||||
<li><button class="btn btn-link" type="submit" name="delete_poll">{_('Remove the poll')}</button></li>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="name-form" class="form-group col-md-5">
|
||||
<h4 class="control-label">{_('Initiator of the poll')}</h4>
|
||||
<p class="form-control-static">{$poll->admin_name|html}{if $admin && !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the initiator')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</p>
|
||||
{if $admin && !$expired}
|
||||
<div class="hidden js-name">
|
||||
<label class="sr-only" for="newname">{_('Initiator of the poll')}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="newname" name="name" size="40" value="{$poll->admin_name|html}" />
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-success" name="update_poll_info" value="name" title="{_('Save the new name')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{_('Cancel the name edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{if $admin}
|
||||
<div class="form-group col-md-5">
|
||||
<div id="email-form">
|
||||
<p>{$poll->admin_mail|html}{if !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the email adress')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</p>
|
||||
{if !$expired}
|
||||
<div class="hidden js-email">
|
||||
<label class="sr-only" for="admin_mail">{_('Email adress')}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="admin_mail" name="admin_mail" size="40" value="{$poll->admin_mail|html}" />
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" name="update_poll_info" value="admin_mail" class="btn btn-success" title="{_('Save the email address')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{_('Cancel the email address edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group col-md-7" id="description-form">
|
||||
<h4 class="control-label">{_("Description")}{if $admin && !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the description')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</h4>
|
||||
<p class="form-control-static well">{$poll->description|html}</p>
|
||||
{if $admin && !$expired}
|
||||
<div class="hidden js-desc text-right">
|
||||
<label class="sr-only" for="newdescription">{_('Description')}</label>
|
||||
<textarea class="form-control" id="newdescription" name="comment" rows="2" cols="40">{$poll->description|html}</textarea>
|
||||
<button type="submit" id="btn-new-desc" name="update_poll_info" value="comment" class="btn btn-sm btn-success" title="{_('Save the description')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-default btn-sm btn-cancel" title="{_('Cancel the description edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group form-group {if $admin}col-md-4{else}col-md-6{/if}">
|
||||
<label for="public-link"><a class="public-link" href="{$poll_id|poll_url|html}">{_('Public link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
|
||||
<input class="form-control" id="public-link" type="text" readonly="readonly" value="{$poll_id|poll_url}" />
|
||||
</div>
|
||||
{if $admin}
|
||||
<div class="form-group col-md-4">
|
||||
<label for="admin-link"><a class="admin-link" href="{$admin_poll_id|poll_url:true|html}">{_('Admin link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
|
||||
<input class="form-control" id="admin-link" type="text" readonly="readonly" value="{$admin_poll_id|poll_url:true|html}" />
|
||||
</div>
|
||||
<div id="expiration-form" class="form-group col-md-4">
|
||||
<h4 class="control-label">{_('Expiration\'s date')}</h4>
|
||||
<p>{$poll->end_date|date_format:$date_format['txt_date']|html}{if !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the expiration\'s date')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</p>
|
||||
{if !$expired}
|
||||
<div class="hidden js-expiration">
|
||||
<label class="sr-only" for="newexpirationdate">{_('Expiration\'s date')}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="newexpirationdate" name="expiration_date" size="40" value="{$poll->end_date|date_format:$date_format['txt_date']|html}" />
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-success" name="update_poll_info" value="expiration_date" title="{_('Save the new expiration date')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{_('Cancel the expiration date edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{if $admin}
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-8" >
|
||||
<div id="poll-rules-form">
|
||||
{if $poll->active}
|
||||
{if $poll->editable}
|
||||
{$rule_id = 2}
|
||||
{$rule_icon = '<span class="glyphicon glyphicon-edit"></span>'}
|
||||
{$rule_txt = _('Votes are editable')}
|
||||
{else}
|
||||
{$rule_id = 1}
|
||||
{$rule_icon = '<span class="glyphicon glyphicon-check"></span>'}
|
||||
{$rule_txt = _('Votes and comments are open')}
|
||||
{/if}
|
||||
{else}
|
||||
{$rule_id = 0}
|
||||
{$rule_icon = '<span class="glyphicon glyphicon-lock"></span>'}
|
||||
{$rule_txt = _('Votes and comments are locked')}
|
||||
{/if}
|
||||
<p class="">{$rule_icon} {$rule_txt|html}{if !$expired} <button class="btn btn-link btn-sm btn-edit" title="{_('Edit the poll rules')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span></button>{/if}</p>
|
||||
{if !$expired}
|
||||
<div class="hidden js-poll-rules">
|
||||
<label class="sr-only" for="rules">{_('Poll rules')}</label>
|
||||
<div class="input-group">
|
||||
<select class="form-control" id="rules" name="rules">
|
||||
<option value="0"{if $rule_id==0} selected="selected"{/if}>{_("Votes and comments are locked")}</option>
|
||||
<option value="1"{if $rule_id==1} selected="selected"{/if}>{_("Votes and comments are open")}</option>
|
||||
<option value="2"{if $rule_id==2} selected="selected"{/if}>{_("Votes are editable")}</option>
|
||||
</select>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" name="update_poll_info" value="rules" class="btn btn-success" title="{_('Save the new rules')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{_('Cancel the rules edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{_('Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{if $admin}</form>{/if}
|
196
tpl/part/vote_table_classic.tpl
Normal file
196
tpl/part/vote_table_classic.tpl
Normal file
@ -0,0 +1,196 @@
|
||||
{if !is_array($best_choices) || empty($best_choices)}
|
||||
{$best_choices = [0]}
|
||||
{/if}
|
||||
|
||||
<h3>{_('Votes of the poll')}</h3>
|
||||
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<form action="" method="POST">
|
||||
<table class="results">
|
||||
<caption class="sr-only">{_('Votes of the poll')} {$poll->title|html}</caption>
|
||||
<thead>
|
||||
{if $admin && !$expired}
|
||||
<tr class="hidden-print">
|
||||
<th role="presentation"></th>
|
||||
{foreach $slots as $id=>$slot}
|
||||
<td headers="C{$id}">
|
||||
<button type="submit" name="delete_column" value="{$slot->title|html}" class="btn btn-link btn-sm" title="{_('Remove the column')} {$slot->title|html}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span></button>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td>
|
||||
<button type="submit" name="add_slot" class="btn btn-link btn-sm" title="{_('Add a column')}"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">{_('Add a column')}</span></button>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
<tr>
|
||||
<th role="presentation"></th>
|
||||
{foreach $slots as $id=>$slot}
|
||||
<th class="bg-info" id="C{$id}">{$slot->title|html|markdown}</th>
|
||||
{/foreach}
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $votes as $vote}
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId == $vote->id}
|
||||
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="text" id="name" name="name" value="{$vote->name|html}" class="form-control" title="{_('Your name')}" placeholder="{_('Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
|
||||
<td class="bg-info" headers="C{$id}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{_('Vote yes for ')} . $radio_title[$id] . '">{* TODO Replace $radio_title *}
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1" {if $choice==1}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{_('Vote ifneedbe for ')} . $radio_title[$id] . '">{* TODO Replace $radio_title *}
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0" {if $choice==0}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{_('Vote no for ')} . $radio_title[$id] . '">{* TODO Replace $radio_title *}
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{_('No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{_('Save the choices')} {$vote->name|html}">{_('Save')}</button></td>
|
||||
{else}
|
||||
|
||||
{* Voted line *}
|
||||
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="C{$id}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="C{$id}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td class="bg-danger" headers="C{$id}"><span class="sr-only">{_('No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && $poll->editable && !$expired}
|
||||
<td>
|
||||
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{_('Edit the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span>
|
||||
</button>
|
||||
{if $admin}
|
||||
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{_('Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span>
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/if}
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId == 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="text" id="name" name="name" class="form-control" title="{_('Your name')}" placeholder="{_('Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
{foreach $slots as $id=>$slot}
|
||||
<td class="bg-info" headers="C{$id}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" />
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{_('Vote yes for')} {$slot->title|html}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1" />
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{_('Vote ifneedbe for')} {$slot->title|html}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0" checked/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{_('Vote no for')} {$slot->title|html}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{_('No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td><button type="submit" class="btn btn-success btn-md" name="save" title="{_('Save the choices')}">{_('Save')}</button></td>
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{_("Addition")}</td>
|
||||
{foreach $best_choices as $best_choice}
|
||||
{if $max == $best_choice}
|
||||
{$count_bests = $count_bests +1}
|
||||
<td><span class="glyphicon glyphicon-star text-warning"></span>{$best_choice|html}</td>
|
||||
{else}
|
||||
<td>{$best_choice|html}</td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{* Best votes listing *}
|
||||
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<div class="row">
|
||||
{if $count_bests == 1}
|
||||
<div class="col-sm-12"><h3>{_("Best choice")}</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{_('The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{_("Best choices")}</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{_('The bests choices at this time are:')}</p>
|
||||
{/if}
|
||||
|
||||
|
||||
{$i = 0}
|
||||
<ul style="list-style:none">
|
||||
{foreach $slots as $slot}
|
||||
{if $best_choices[$i] == $max}
|
||||
<li><strong>{$slot->title|html|markdown:true}</strong></li>
|
||||
{/if}
|
||||
{$i = $i+1}
|
||||
{/foreach}
|
||||
</ul>
|
||||
<p>{_('with')} <b>{$max|html}</b> {if $max==1}{_('vote')}{else}{_('votes')}{/if}.</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
246
tpl/part/vote_table_date.tpl
Normal file
246
tpl/part/vote_table_date.tpl
Normal file
@ -0,0 +1,246 @@
|
||||
{if !is_array($best_choices) || empty($best_choices)}
|
||||
{$best_choices = [0]}
|
||||
{/if}
|
||||
|
||||
<h3>{_('Votes of the poll')}</h3>
|
||||
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<form action="" method="POST">
|
||||
<table class="results">
|
||||
<caption class="sr-only">{_('Votes of the poll')} {$poll->title|html}</caption>
|
||||
<thead>
|
||||
{if $admin && !$expired}
|
||||
<tr class="hidden-print">
|
||||
<th role="presentation"></th>
|
||||
{$headersDCount=0}
|
||||
{foreach $slots as $slot}
|
||||
{foreach $slot->moments as $id=>$moment}
|
||||
<td headers="M{$slot@key} D{$headersDCount} H{$headersDCount}">
|
||||
<button type="submit" name="delete_column" value="{$slot->day|html}@{$moment|html}" class="btn btn-link btn-sm" title="{_('Remove the column')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span></button>
|
||||
</td>
|
||||
{$headersDCount = $headersDCount+1}
|
||||
{/foreach}
|
||||
{/foreach}
|
||||
<td>
|
||||
<button type="submit" name="add_slot" class="btn btn-link btn-sm" title="{_('Add a column')}"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">{_("Add a column")}</span></button>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
<tr>
|
||||
<th role="presentation"></th>
|
||||
{$count_same = 0}
|
||||
{$previous = 0}
|
||||
{foreach $slots as $id=>$slot}
|
||||
{$display = $slot->day|date_format:$date_format.txt_year_month|html}
|
||||
{if $previous !== 0 && $previous != $display}
|
||||
<th colspan="{$count_same}" class="bg-primary month" id="M{$id}">{$previous}</th>
|
||||
{$count_same = 0}
|
||||
{/if}
|
||||
|
||||
{$count_same = $count_same + $slot->moments|count}
|
||||
|
||||
{if $slot@last}
|
||||
<th colspan="{$count_same}" class="bg-primary month" id="M{$id}">{$display}</th>
|
||||
{/if}
|
||||
|
||||
{$previous = $display}
|
||||
|
||||
{for $foo=0 to ($slot->moments|count)-1}
|
||||
{append var='headersM' value=$id}
|
||||
{/for}
|
||||
{/foreach}
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th role="presentation"></th>
|
||||
{foreach $slots as $id=>$slot}
|
||||
<th colspan="{$slot->moments|count}" class="bg-primary day" id="D{$id}">{$slot->day|date_format:$date_format.txt_day|html}</th>
|
||||
{for $foo=0 to ($slot->moments|count)-1}
|
||||
{append var='headersD' value=$id}
|
||||
{/for}
|
||||
{/foreach}
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th role="presentation"></th>
|
||||
{$headersDCount=0}
|
||||
{foreach $slots as $slot}
|
||||
{foreach $slot->moments as $id=>$moment}
|
||||
<th colspan="1" class="bg-info" id="H{$headersDCount}">{$moment|html}</th>
|
||||
{append var='headersH' value=$headersDCount}
|
||||
{$headersDCount = $headersDCount+1}
|
||||
{/foreach}
|
||||
{/foreach}
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $votes as $vote}
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId == $vote->id && !$expired}
|
||||
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="text" id="name" name="name" value="{$vote->name|html}" class="form-control" title="{_('Your name')}" placeholder="{_('Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
|
||||
<td class="bg-info" headers="M{$headersM[$k]} D{$headersD[$k]} H{$headersH[$k]}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$k}" name="choices[{$k}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$k}" title="{_('Vote yes for ')} . $radio_title[$k] . '">{* TODO Replace $radio_title *}
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$k}" name="choices[{$k}]" value="1" {if $choice==1}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$k}" title="{_('Vote ifneedbe for ')} . $radio_title[$k] . '">{* TODO Replace $radio_title *}
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$k}" name="choices[{$k}]" value="0" {if $choice==0}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$k}" title="{_('Vote no for ')} . $radio_title[$k] . '">{* TODO Replace $radio_title *}
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{_('No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{_('Save the choices')} {$vote->name|html}">{_('Save')}</button></td>
|
||||
{else}
|
||||
|
||||
{* Voted line *}
|
||||
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td class="bg-danger" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="sr-only">{_('No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && $poll->editable && !$expired}
|
||||
<td>
|
||||
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{_('Edit the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{_('Edit')}</span>
|
||||
</button>
|
||||
{if $admin}
|
||||
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{_('Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{_('Remove')}</span>
|
||||
</button>
|
||||
{/if}
|
||||
</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/if}
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId == 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="text" id="name" name="name" class="form-control" title="{_('Your name')}" placeholder="{_('Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
{$i = 0}
|
||||
{foreach $slots as $slot}
|
||||
{foreach $slot->moments as $moment}
|
||||
<td class="bg-info" headers="M{$headersM[$i]} D{$headersD[$i]} H{$headersH[$i]}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$i}" name="choices[{$i}]" value="2" />
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$i}" title="{_('Vote yes for')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{_('Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$i}" name="choices[{$i}]" value="1" />
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$i}" title="{_('Vote ifneedbe for')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{_('Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value="0" checked/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$i}" title="{_('Vote no for')} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{_('No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{$i = $i+1}
|
||||
{/foreach}
|
||||
{/foreach}
|
||||
<td><button type="submit" class="btn btn-success btn-md" name="save" title="{_('Save the choices')}">{_('Save')}</button></td>
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{_("Addition")}</td>
|
||||
{foreach $best_choices as $best_moment}
|
||||
{if $max == $best_moment}
|
||||
{$count_bests = $count_bests +1}
|
||||
<td><i class="glyphicon glyphicon-star text-warning"></i>{$best_moment|html}</td>
|
||||
{else}
|
||||
<td>{$best_moment|html}</td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{* Best votes listing *}
|
||||
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<div class="row">
|
||||
{if $count_bests == 1}
|
||||
<div class="col-sm-12"><h3>{_('Best choice')}</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{_('The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{_('Best choices')}</h3></div>
|
||||
<div class="col-sm-6 col-sm-offset-3 alert alert-success">
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{_('The bests choices at this time are:')}</p>
|
||||
{/if}
|
||||
|
||||
|
||||
{$i = 0}
|
||||
<ul style="list-style:none">
|
||||
{foreach $slots as $slot}
|
||||
{foreach $slot->moments as $moment}
|
||||
{if $best_choices[$i] == $max}
|
||||
<li><strong>{$slot->day|date_format:$date_format.txt_full|html} - {$moment|html}</strong></li>
|
||||
{/if}
|
||||
{$i = $i+1}
|
||||
{/foreach}
|
||||
{/foreach}
|
||||
</ul>
|
||||
<p>{_('with')} <b>{$max|html}</b> {if $max==1}{_('vote')}{else}{_('votes')}{/if}.</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
8
tpl/poll_deleted.tpl
Normal file
8
tpl/poll_deleted.tpl
Normal file
@ -0,0 +1,8 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<div class="alert alert-success text-center">
|
||||
<h2>{_("Your poll has been removed!")}</h2>
|
||||
<p>{_('Back to the homepage of')} <a href="{$SERVER_URL|html}">{$APPLICATION_NAME|html}</a></p>
|
||||
</div>
|
||||
{/block}
|
52
tpl/studs.tpl
Normal file
52
tpl/studs.tpl
Normal file
@ -0,0 +1,52 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
|
||||
{if !empty($message)}
|
||||
<div class="alert alert-dismissible alert-{$message->type|html}" role="alert">{$message->message|html}<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>
|
||||
{/if}
|
||||
|
||||
{* Global informations about the current poll *}
|
||||
|
||||
{include 'part/poll_info.tpl' admin=$admin}
|
||||
|
||||
{* Information about voting *}
|
||||
{if $expired}
|
||||
<div class="alert alert-danger">
|
||||
<p>{_('The poll is expired, it will be deleted soon.')}</p>
|
||||
<p>{_('Deletion date:')} {$deletion_date|date_format:$date_format['txt_short']|html}</p>
|
||||
</div>
|
||||
{else}
|
||||
{if $admin}
|
||||
{include 'part/poll_hint_admin.tpl'}
|
||||
{else}
|
||||
{include 'part/poll_hint.tpl' active=$poll->active}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{* Scroll left and right *}
|
||||
|
||||
<div class="hidden row scroll-buttons" aria-hidden="true">
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn btn-sm btn-link scroll-left" title="{_('Scroll to the left')}">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-link scroll-right" title="{_('Scroll to the right')}">
|
||||
<span class="glyphicon glyphicon-chevron-right"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* Vote table *}
|
||||
|
||||
{if $poll->format === 'D'}
|
||||
{include 'part/vote_table_date.tpl' active=$poll->active}
|
||||
{else}
|
||||
{include 'part/vote_table_classic.tpl' active=$poll->active}
|
||||
{/if}
|
||||
|
||||
{* Comments *}
|
||||
|
||||
{include 'part/comments.tpl' active=$poll->active comments=$comments}
|
||||
|
||||
{/block}
|
Loading…
Reference in New Issue
Block a user