Merge branch 'feature/hidden-and-private-polls' into 'develop'
Feature/hidden and private polls **Added an option for the poll's hidden results** - At poll creation, a new checkbox is added to hide the results - At poll visualization, results are hidden if option is activated - At poll edition by the poll maker, the hidden option can be changed **Added a new edition option** - At poll creation, we can choose between "no user modification" and "all users can modify every vote" like before. But we can now also select "each vote can be modified by its owner" - This edition option is also available for the poll maker in the poll administration interface - When a user votes with this new option activated, an edition link is displayed to him : only this link can allow the user to modify its vote. - This functionality will be useful to create "private polls" later. **Side work** - The token generation is now safer, with fallback to unsafe version if the php functions are not available - An anchor is added to the edit link, to scroll down to the current line that the user is editing - Commited composer.lock (good practice) - Added the root htaccess.txt to keep the CLEAN_URL format updated - The Message class can now contain a link (only displayed in studs.php where I needed it) See merge request !45
This commit is contained in:
commit
e26af38b35
@ -20,6 +20,8 @@
|
||||
use Framadate\Migration\From_0_0_to_0_8_Migration;
|
||||
use Framadate\Migration\From_0_8_to_0_9_Migration;
|
||||
use Framadate\Migration\AddColumn_receiveNewComments_For_0_9;
|
||||
use Framadate\Migration\AddColumn_uniqId_In_vote_For_0_9;
|
||||
use Framadate\Migration\AddColumn_hidden_In_poll_For_0_9;
|
||||
use Framadate\Migration\Migration;
|
||||
use Framadate\Utils;
|
||||
|
||||
@ -31,7 +33,9 @@ set_time_limit(300);
|
||||
$migrations = [
|
||||
new From_0_0_to_0_8_Migration(),
|
||||
new From_0_8_to_0_9_Migration(),
|
||||
new AddColumn_receiveNewComments_For_0_9()
|
||||
new AddColumn_receiveNewComments_For_0_9(),
|
||||
new AddColumn_uniqId_In_vote_For_0_9(),
|
||||
new AddColumn_hidden_In_poll_For_0_9(),
|
||||
];
|
||||
// ---------------------------------------
|
||||
|
||||
|
@ -22,6 +22,7 @@ use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
@ -45,10 +46,12 @@ $inputService = new InputService();
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
if (!empty($_GET['poll']) && strlen($_GET['poll']) === 24) {
|
||||
if (!empty($_GET['poll'])) {
|
||||
$admin_poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll_id = substr($admin_poll_id, 0, 16);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
if (strlen($admin_poll_id) === 24) {
|
||||
$poll_id = substr($admin_poll_id, 0, 16);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$poll) {
|
||||
@ -63,7 +66,7 @@ if (!$poll) {
|
||||
|
||||
if (isset($_POST['update_poll_info'])) {
|
||||
$updated = false;
|
||||
$field = $inputService->filterAllowedValues($_POST['update_poll_info'], ['title', 'admin_mail', 'description', 'rules', 'expiration_date', 'name']);
|
||||
$field = $inputService->filterAllowedValues($_POST['update_poll_info'], ['title', 'admin_mail', 'description', 'rules', 'expiration_date', 'name', 'hidden']);
|
||||
|
||||
// Update the right poll field
|
||||
if ($field == 'title') {
|
||||
@ -89,17 +92,22 @@ if (isset($_POST['update_poll_info'])) {
|
||||
switch ($rules) {
|
||||
case 0:
|
||||
$poll->active = false;
|
||||
$poll->editable = false;
|
||||
$poll->editable = Editable::NOT_EDITABLE;
|
||||
$updated = true;
|
||||
break;
|
||||
case 1:
|
||||
$poll->active = true;
|
||||
$poll->editable = false;
|
||||
$poll->editable = Editable::NOT_EDITABLE;
|
||||
$updated = true;
|
||||
break;
|
||||
case 2:
|
||||
$poll->active = true;
|
||||
$poll->editable = true;
|
||||
$poll->editable = Editable::EDITABLE_BY_ALL;
|
||||
$updated = true;
|
||||
break;
|
||||
case 3:
|
||||
$poll->active = true;
|
||||
$poll->editable = Editable::EDITABLE_BY_OWN;
|
||||
$updated = true;
|
||||
break;
|
||||
}
|
||||
@ -116,6 +124,13 @@ if (isset($_POST['update_poll_info'])) {
|
||||
$poll->admin_name = $admin_name;
|
||||
$updated = true;
|
||||
}
|
||||
} elseif ($field == 'hidden') {
|
||||
$hidden = filter_input(INPUT_POST, 'hidden', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
$hidden = $hidden==null?false:true;
|
||||
if ($hidden != $poll->hidden) {
|
||||
$poll->hidden = $hidden;
|
||||
$updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update poll in database
|
||||
@ -131,8 +146,8 @@ if (isset($_POST['update_poll_info'])) {
|
||||
// A vote is going to be edited
|
||||
// -------------------------------
|
||||
|
||||
if (!empty($_POST['edit_vote'])) {
|
||||
$editingVoteId = filter_input(INPUT_POST, 'edit_vote', FILTER_VALIDATE_INT);
|
||||
if (!empty($_GET['vote'])) {
|
||||
$editingVoteId = filter_input(INPUT_GET, 'vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
@ -373,6 +388,7 @@ $smarty->assign('comments', $comments);
|
||||
$smarty->assign('editingVoteId', $editingVoteId);
|
||||
$smarty->assign('message', $message);
|
||||
$smarty->assign('admin', true);
|
||||
$smarty->assign('hidden', $poll->hidden);
|
||||
$smarty->assign('parameter_name_regex', NAME_REGEX);
|
||||
|
||||
$smarty->display('studs.tpl');
|
37
app/classes/Framadate/Editable.php
Normal file
37
app/classes/Framadate/Editable.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?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 Editable
|
||||
*
|
||||
* Is used to specify the poll's edition permissions.
|
||||
* @TODO : wait to use the SplEnum
|
||||
*
|
||||
* @package Framadate
|
||||
*/
|
||||
class Editable { // extends SplEnum
|
||||
const __default = self::EDITABLE_BY_ALL;
|
||||
|
||||
const NOT_EDITABLE = 0;
|
||||
const EDITABLE_BY_ALL = 1;
|
||||
const EDITABLE_BY_OWN = 2;
|
||||
}
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
use Framadate\Editable;
|
||||
|
||||
class Form
|
||||
{
|
||||
|
||||
@ -31,6 +33,7 @@ class Form
|
||||
|
||||
/**
|
||||
* Tells if users can modify their choices.
|
||||
* @var \Framadate\Editable
|
||||
*/
|
||||
public $editable;
|
||||
|
||||
@ -44,13 +47,19 @@ class Form
|
||||
*/
|
||||
public $receiveNewComments;
|
||||
|
||||
/**
|
||||
* If true, only the poll maker can see the poll's results
|
||||
* @var boolean
|
||||
*/
|
||||
public $hidden;
|
||||
|
||||
/**
|
||||
* List of available choices
|
||||
*/
|
||||
private $choices;
|
||||
|
||||
public function __construct(){
|
||||
$this->editable = true;
|
||||
$this->editable = Editable::EDITABLE_BY_ALL;
|
||||
$this->clearChoices();
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,9 @@ class FramaDB {
|
||||
}
|
||||
|
||||
function updatePoll($poll) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=?, active=?, editable=? WHERE id = ?');
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=?, active=?, editable=?, hidden=? WHERE id = ?');
|
||||
|
||||
return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->id]);
|
||||
return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->hidden, $poll->id]);
|
||||
}
|
||||
|
||||
function allCommentsByPollId($poll_id) {
|
||||
@ -122,15 +122,16 @@ class FramaDB {
|
||||
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]);
|
||||
function insertVote($poll_id, $name, $choices, $token) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices, uniqId) VALUES (?,?,?,?)');
|
||||
$prepared->execute([$poll_id, $name, $choices, $token]);
|
||||
|
||||
$newVote = new \stdClass();
|
||||
$newVote->poll_id = $poll_id;
|
||||
$newVote->id = $this->pdo->lastInsertId();
|
||||
$newVote->name = $name;
|
||||
$newVote->choices = $choices;
|
||||
$newVote->uniqId = $token;
|
||||
|
||||
return $newVote;
|
||||
}
|
||||
|
@ -22,10 +22,12 @@ class Message {
|
||||
|
||||
var $type;
|
||||
var $message;
|
||||
var $link;
|
||||
|
||||
function __construct($type, $message) {
|
||||
function __construct($type, $message, $link=null) {
|
||||
$this->type = $type;
|
||||
$this->message = $message;
|
||||
$this->link = $link;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
<?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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field hidden on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_hidden_In_poll_For_0_9 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 'Add column "hidden" in table "vote" for version 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.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 `hidden` TINYINT( 1 ) NOT NULL DEFAULT "0"');
|
||||
}
|
||||
|
||||
}
|
@ -37,7 +37,7 @@ class AddColumn_receiveNewComments_For_0_9 implements Migration {
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "Add column \"receiveNewComments\" for version 0.9";
|
||||
return 'Add column "receiveNewComments" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,79 @@
|
||||
<?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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field uniqId on the vote table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_uniqId_In_vote_For_0_9 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 'Add column "uniqId" in table "vote" for version 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.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('vote') . '`
|
||||
ADD `uniqId` CHAR(16) NOT NULL
|
||||
AFTER `id`,
|
||||
ADD INDEX (`uniqId`) ;');
|
||||
}
|
||||
|
||||
}
|
@ -37,7 +37,7 @@ class From_0_0_to_0_8_Migration implements Migration {
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "First installation of the Framadate application (v0.8)";
|
||||
return 'First installation of the Framadate application (v0.8)';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@ class From_0_8_to_0_9_Migration implements Migration {
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return "From 0.8 to 0.9";
|
||||
return 'From 0.8 to 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,14 +5,17 @@ class Token {
|
||||
|
||||
private $time;
|
||||
private $value;
|
||||
private $length;
|
||||
private static $codeAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
|
||||
|
||||
function __construct() {
|
||||
function __construct($length = 64) {
|
||||
$this->length = $length;
|
||||
$this->time = time() + TOKEN_TIME;
|
||||
$this->value = $this->generate();
|
||||
}
|
||||
|
||||
private function generate() {
|
||||
return sha1(uniqid(mt_rand(), true));
|
||||
return self::getToken($this->length);
|
||||
}
|
||||
|
||||
public function getTime() {
|
||||
@ -31,5 +34,58 @@ class Token {
|
||||
return $value === $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a secure token if possible, or a less secure one if not.
|
||||
*
|
||||
* @param int $length The token length
|
||||
* @param bool $crypto_strong If passed, tells if the token is "cryptographically strong" or not.
|
||||
* @return string
|
||||
*/
|
||||
public static function getToken($length, &$crypto_strong = false) {
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
openssl_random_pseudo_bytes(1, $crypto_strong); // Fake use to see if the algorithm used was "cryptographically strong"
|
||||
return self::getSecureToken($length);
|
||||
}
|
||||
return self::getUnsecureToken($length);
|
||||
}
|
||||
|
||||
public static function getUnsecureToken($length) {
|
||||
$string = '';
|
||||
mt_srand();
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$string .= self::$codeAlphabet[mt_rand() % strlen(self::$codeAlphabet)];
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author http://stackoverflow.com/a/13733588
|
||||
*/
|
||||
public static function getSecureToken($length){
|
||||
$token = "";
|
||||
for($i=0;$i<$length;$i++){
|
||||
$token .= self::$codeAlphabet[self::crypto_rand_secure(0,strlen(self::$codeAlphabet))];
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
|
||||
*/
|
||||
private static function crypto_rand_secure($min, $max) {
|
||||
$range = $max - $min;
|
||||
if ($range < 0) return $min; // not so random...
|
||||
$log = log($range, 2);
|
||||
$bytes = (int) ($log / 8) + 1; // length in bytes
|
||||
$bits = (int) $log + 1; // length in bits
|
||||
$filter = (int) (1 << $bits) - 1; // set all lower bits to 1
|
||||
do {
|
||||
$rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
|
||||
$rnd = $rnd & $filter; // discard irrelevant bits
|
||||
} while ($rnd >= $range);
|
||||
return $min + $rnd;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Framadate\Services;
|
||||
use Framadate\Form;
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Security\Token;
|
||||
|
||||
class PollService {
|
||||
|
||||
@ -66,8 +67,8 @@ class PollService {
|
||||
|
||||
function addVote($poll_id, $name, $choices) {
|
||||
$choices = implode($choices);
|
||||
|
||||
return $this->connect->insertVote($poll_id, $name, $choices);
|
||||
$token = $this->random(16);
|
||||
return $this->connect->insertVote($poll_id, $name, $choices, $token);
|
||||
}
|
||||
|
||||
function addComment($poll_id, $name, $comment) {
|
||||
@ -115,6 +116,7 @@ class PollService {
|
||||
$obj = new \stdClass();
|
||||
$obj->id = $vote->id;
|
||||
$obj->name = $vote->name;
|
||||
$obj->uniqId = $vote->uniqId;
|
||||
$obj->choices = str_split($vote->choices);
|
||||
|
||||
$splitted[] = $obj;
|
||||
@ -176,15 +178,8 @@ class PollService {
|
||||
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;
|
||||
private function random($length) {
|
||||
return Token::getToken($length);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -97,23 +97,30 @@ class Utils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return string L'url pour le sondage
|
||||
* Function allowing to generate poll's url
|
||||
* @param string $id The poll's id
|
||||
* @param bool $admin True to generate an admin URL, false for a public one
|
||||
* @param string $vote_id (optional) The vote's unique id
|
||||
* @return string The poll's URL.
|
||||
*/
|
||||
public static function getUrlSondage($id, $admin = false) {
|
||||
public static function getUrlSondage($id, $admin = false, $vote_id='') {
|
||||
if (URL_PROPRE) {
|
||||
if ($admin === true) {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . $id . '/admin';
|
||||
} else {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . $id;
|
||||
if ($vote_id != '') {
|
||||
$url .= '/vote/'.$vote_id."#edit";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($admin === true) {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'adminstuds.php?poll=' . $id;
|
||||
} else {
|
||||
$url = str_replace('/admin', '', self::get_server_name()) . 'studs.php?poll=' . $id;
|
||||
if ($vote_id != '') {
|
||||
$url .= '&vote='.$vote_id."#edit";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,11 @@
|
||||
const VERSION = '0.9';
|
||||
|
||||
// Regex
|
||||
const POLL_REGEX = '/^[a-z0-9]+$/';
|
||||
const POLL_REGEX = '/^[a-zA-Z0-9]+$/';
|
||||
const CHOICE_REGEX = '/^[012]$/';
|
||||
const NAME_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9_ -]+$/i';
|
||||
const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/';
|
||||
const EDITABLE_CHOICE_REGEX = '/^[0-2]$/';
|
||||
|
||||
// CSRF (300s = 5min)
|
||||
const TOKEN_TIME = 300;
|
||||
|
@ -34,8 +34,25 @@ $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);
|
||||
// Dev Mode
|
||||
if (isset($_SERVER['FRAMADATE_DEVMODE']) && $_SERVER['FRAMADATE_DEVMODE']) {
|
||||
$smarty->force_compile = true;
|
||||
$smarty->compile_check = true;
|
||||
|
||||
} else {
|
||||
$smarty->force_compile = false;
|
||||
$smarty->compile_check = false;
|
||||
}
|
||||
|
||||
|
||||
function smarty_function_poll_url($params, Smarty_Internal_Template $template) {
|
||||
$poll_id = filter_var($params['id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$admin = (isset($params['admin']) && $params['admin']) ? true : false;
|
||||
$vote_unique_id = isset($params['vote_id']) ? filter_var($params['vote_id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]) : '';
|
||||
|
||||
// If filter_var fails (i.e.: hack tentative), it will return false. At least no leak is possible from this.
|
||||
|
||||
return Utils::getUrlSondage($poll_id, $admin, $vote_unique_id);
|
||||
}
|
||||
|
||||
function smarty_modifier_markdown($md, $clear = false) {
|
||||
|
12
composer.lock
generated
12
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "4771fa2616869cff821e2bf1daa6245c",
|
||||
"hash": "35bdfd24b481ad94a99b6fd67499aba9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "o80/i18n",
|
||||
@ -12,12 +12,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/olivierperez/o80-i18n.git",
|
||||
"reference": "830112445b557068b9fe02b576d5cf770fcdf037"
|
||||
"reference": "669befcdadf3a745193792f51e97af1e70b3e614"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/olivierperez/o80-i18n/zipball/830112445b557068b9fe02b576d5cf770fcdf037",
|
||||
"reference": "830112445b557068b9fe02b576d5cf770fcdf037",
|
||||
"url": "https://api.github.com/repos/olivierperez/o80-i18n/zipball/669befcdadf3a745193792f51e97af1e70b3e614",
|
||||
"reference": "669befcdadf3a745193792f51e97af1e70b3e614",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -50,9 +50,7 @@
|
||||
"internationalization",
|
||||
"php"
|
||||
],
|
||||
"time": "2015-03-21 22:37:40"
|
||||
"time": "2015-03-27 19:37:27"
|
||||
"time": "2015-03-23 21:40:47"
|
||||
"time": "2015-03-30 22:20:26"
|
||||
},
|
||||
{
|
||||
"name": "smarty/smarty",
|
||||
|
@ -4,20 +4,21 @@
|
||||
* 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 STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Rapha<EFBFBD>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
|
||||
* Ce logiciel est r<EFBFBD>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 STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Rapha<EFBFBD>l DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Form;
|
||||
use Framadate\Editable;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
@ -45,26 +46,28 @@ $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]]);
|
||||
$editable = filter_input(INPUT_POST, 'editable', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => EDITABLE_CHOICE_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]]);
|
||||
$hidden = filter_input(INPUT_POST, 'hidden', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
|
||||
|
||||
// On initialise également les autres variables
|
||||
// On initialise <EFBFBD>galement les autres variables
|
||||
$error_on_mail = false;
|
||||
$error_on_title = false;
|
||||
$error_on_name = false;
|
||||
$error_on_description = false;
|
||||
|
||||
//
|
||||
|
||||
if (!empty($_POST[GO_TO_STEP_2])) {
|
||||
$_SESSION['form']->title = $title;
|
||||
$_SESSION['form']->admin_name = $name;
|
||||
$_SESSION['form']->admin_mail = $mail;
|
||||
$_SESSION['form']->description = $description;
|
||||
$_SESSION['form']->editable = ($editable !== null);
|
||||
$_SESSION['form']->editable = $editable;
|
||||
$_SESSION['form']->receiveNewVotes = ($receiveNewVotes !== null);
|
||||
$_SESSION['form']->receiveNewComments = ($receiveNewComments !== null);
|
||||
$_SESSION['form']->hidden = ($hidden !== null);
|
||||
|
||||
if ($config['use_smtp'] == true) {
|
||||
if (empty($mail)) {
|
||||
@ -174,20 +177,6 @@ if (!empty($_POST[GO_TO_STEP_2])) {
|
||||
}
|
||||
}
|
||||
|
||||
// Checkbox checked ?
|
||||
if ($_SESSION['form']->editable) {
|
||||
$editable = 'checked';
|
||||
}
|
||||
|
||||
if ($_SESSION['form']->receiveNewVotes) {
|
||||
$receiveNewVotes = 'checked';
|
||||
}
|
||||
|
||||
if ($_SESSION['form']->receiveNewComments) {
|
||||
$receiveNewComments = 'checked';
|
||||
}
|
||||
|
||||
|
||||
$useRemoteUser = USE_REMOTE_USER && isset($_SERVER['REMOTE_USER']);
|
||||
|
||||
$smarty->assign('title', $title);
|
||||
@ -204,6 +193,7 @@ $smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $_SESSION['form']-
|
||||
$smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $_SESSION['form']->editable));
|
||||
$smarty->assign('poll_receiveNewVotes', Utils::fromPostOrDefault('receiveNewVotes', $_SESSION['form']->receiveNewVotes));
|
||||
$smarty->assign('poll_receiveNewComments', Utils::fromPostOrDefault('receiveNewComments', $_SESSION['form']->receiveNewComments));
|
||||
$smarty->assign('poll_hidden', Utils::fromPostOrDefault('hidden', $_SESSION['form']->hidden));
|
||||
$smarty->assign('form', $_SESSION['form']);
|
||||
|
||||
$smarty->display('create_poll.tpl');
|
||||
|
@ -124,6 +124,7 @@ caption {
|
||||
#email-form .btn-edit,
|
||||
#description-form .btn-edit,
|
||||
#poll-rules-form .btn-edit,
|
||||
#poll-hidden-form .btn-edit,
|
||||
#expiration-form .btn-edit,
|
||||
#name-form .btn-edit {
|
||||
position:absolute;
|
||||
@ -138,6 +139,8 @@ caption {
|
||||
#description-form:hover .btn-edit,
|
||||
#poll-rules-form .btn-edit:focus,
|
||||
#poll-rules-form:hover .btn-edit,
|
||||
#poll-hidden-form .btn-edit:focus,
|
||||
#poll-hidden-form:hover .btn-edit,
|
||||
#expiration-form .btn-edit:focus,
|
||||
#expiration-form:hover .btn-edit,
|
||||
#name-form .btn-edit:focus,
|
||||
@ -155,7 +158,7 @@ caption {
|
||||
margin-bottom:0;
|
||||
}
|
||||
|
||||
#poll-rules-form p,
|
||||
#poll-rules-form p, #poll-hidden-form p,
|
||||
.jumbotron p.well {
|
||||
font-size:16px;
|
||||
}
|
||||
|
13
htaccess.txt
Normal file
13
htaccess.txt
Normal file
@ -0,0 +1,13 @@
|
||||
######################
|
||||
# .htaccess example. #
|
||||
######################
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
|
||||
RewriteRule ^([a-zA-Z0-9]{16})$ studs.php?poll=$1
|
||||
RewriteRule ^([a-zA-Z0-9]{16})/vote/([a-zA-Z0-9]{16})$ studs.php?poll=$1&vote_id=$2
|
||||
RewriteRule ^([a-zA-Z0-9]{24})/admin$ adminstuds.php?poll=$1
|
||||
</IfModule>
|
54
js/app/create_poll.js
Normal file
54
js/app/create_poll.js
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$("#formulaire").submit(function (event) {
|
||||
var isHidden = $("#hidden").prop('checked');
|
||||
var isOptionAllUserCanModifyEverything = $("#editableByAll").is(":checked");
|
||||
|
||||
if (isHidden && isOptionAllUserCanModifyEverything) {
|
||||
event.preventDefault();
|
||||
$("#hiddenWithBadEditionModeError").removeClass("hidden");
|
||||
} else {
|
||||
$("#hiddenWithBadEditionModeError").addClass("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Check cookies are enabled too
|
||||
var cookieEnabled = function () {
|
||||
var cookieEnabled = navigator.cookieEnabled;
|
||||
|
||||
// if not IE4+ nor NS6+
|
||||
if (!cookieEnabled && typeof navigator.cookieEnabled === "undefined") {
|
||||
document.cookie = "testcookie";
|
||||
cookieEnabled = document.cookie.indexOf("testcookie") != -1;
|
||||
}
|
||||
|
||||
return cookieEnabled;
|
||||
};
|
||||
|
||||
if (cookieEnabled()) {
|
||||
// Show the form block
|
||||
document.getElementById("form-block").setAttribute("style", "");
|
||||
} else {
|
||||
// Show the warning about cookies
|
||||
document.getElementById("cookie-warning").setAttribute("style", "");
|
||||
}
|
||||
|
||||
});
|
@ -3,22 +3,22 @@
|
||||
* 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 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
|
||||
* 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 STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$(".check-name").click(function (event) {
|
||||
$("#poll_form").submit(function (event) {
|
||||
var name = $("#name").val();
|
||||
var regexContent = $("#parameter_name_regex").text().split("/");
|
||||
var regex = new RegExp(regexContent[1], regexContent[2]);
|
||||
|
14
js/core.js
14
js/core.js
@ -76,6 +76,20 @@ $(document).ready(function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#poll-hidden-form .btn-edit').on('click', function() {
|
||||
$('#poll-hidden-form p').hide();
|
||||
$('#poll-hidden-form .js-poll-hidden').removeClass("hidden");
|
||||
$('.js-poll-hidden input[type=checkbox]').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#poll-hidden-form .btn-cancel').on('click', function() {
|
||||
$('#poll-hidden-form p').show();
|
||||
$('#poll-hidden-form .js-poll-hidden').addClass("hidden");
|
||||
$('.js-poll-hidden .btn-edit').focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#expiration-form .btn-edit').on('click', function() {
|
||||
$('#expiration-form p').hide();
|
||||
$('.js-expiration').removeClass("hidden");
|
||||
|
@ -111,9 +111,12 @@
|
||||
"Votes and comments are locked": "Abstimmungen und Kommentare sind gesperrt",
|
||||
"Votes and comments are open": "Abstimmungen und Kommentare sind möglich",
|
||||
"Votes are editable": "Die Abstimmungen können geändert werden",
|
||||
"Votes are editable solely by their owner.": "DE_Les votes sont modifiables uniquement par leur créateur",
|
||||
"Save the new rules": "Neue Regeln speichern",
|
||||
"Cancel the rules edit": "Neue Regeln nicht speichern",
|
||||
"The name is invalid.": "Der Name ist ungültig."
|
||||
"The name is invalid.": "Der Name ist ungültig.",
|
||||
"Results are hidden.": "DE_Les résultats sont cachés.",
|
||||
"Results are visible.": "DE_Les résultats sont visibles."
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Abstimmungen der Umfrage ",
|
||||
@ -144,7 +147,8 @@
|
||||
"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.": "Wenn Sie bei dieser Umfrage abstimmen möchten, müssen Sie ihren Namen angeben. Wählen Sie die Optionen, die für Sie am besten passen und bestätigen Sie diese über den Plus-Button am Ende der Zeile.",
|
||||
"POLL_LOCKED_WARNING": "Die Administration gesperrt diese Umfrage. Bewertungen und Kommentare werden eingefroren, es ist nicht mehr möglich, teilzunehmen",
|
||||
"The poll is expired, it will be deleted soon.": "Die Umfrage ist abgelaufen, es wird bald gelöscht werden.",
|
||||
"Deletion date:": "Löschdatum:"
|
||||
"Deletion date:": "Löschdatum:",
|
||||
"Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "DE_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! "
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "Als Administrator der Umfrage, können Sie alle Zeilen der Umfrage über diesen Button ändern",
|
||||
@ -186,9 +190,12 @@
|
||||
"You are in the poll creation section.": "Sie können hier Umfragen erstellen",
|
||||
"Required fields cannot be left blank.": "Mit * markierte Felder müssen ausgefüllt sein.",
|
||||
"Poll title": "Umfragetitel",
|
||||
"Votes cannot be modified.": "DE_Aucun vote ne peut être modifié",
|
||||
"All voters can modify any vote.": "DE_Tous les sondés peuvent modifier tous les votes",
|
||||
"Voters can modify their vote themselves.": "Teilnehmer können ihre Antworten verändern",
|
||||
"To receive an email for each new vote.": "Bei jeder neuen Abstimmung eine E-Mail erhalten.",
|
||||
"To receive an email for each new comment.": "Um eine E-Mail für jede neue Kommentar zu empfangen.",
|
||||
"Only the poll maker can see the poll's results.": "DE_Seul le créateur du sondage peut voir les résultats.",
|
||||
"Go to step 2": "Weiter zum 2. Schritt"
|
||||
},
|
||||
"Step 2": {
|
||||
@ -297,6 +304,7 @@
|
||||
"Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "Framadate ist nicht richtig installiert, überprüfen Sie bitte die Schaltfläche \"INSTALL\", um das Setup der Datenbank, bevor Sie fortfahren.",
|
||||
"Failed to save poll": "Fehlgeschlagen Umfrage sparen",
|
||||
"Update vote failed": "Update vote failed",
|
||||
"Adding vote failed": "Adding vote failed"
|
||||
"Adding vote failed": "Adding vote failed",
|
||||
"You can't create a poll with hidden results with the following edition option:": "DE_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : "
|
||||
}
|
||||
}
|
@ -112,9 +112,12 @@
|
||||
"Votes and comments are locked": "Votes and comments are locked",
|
||||
"Votes and comments are open": "Votes and comments are open",
|
||||
"Votes are editable": "Votes are editable",
|
||||
"Votes are editable solely by their owner.": "Votes are editable solely by their owner",
|
||||
"Save the new rules": "Save the new rules",
|
||||
"Cancel the rules edit": "Cancel the rules edit",
|
||||
"The name is invalid.": "The name is invalid."
|
||||
"The name is invalid.": "The name is invalid.",
|
||||
"Results are hidden.": "Results are hidden.",
|
||||
"Results are visible.": "Results are visible."
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Votes of the poll",
|
||||
@ -145,7 +148,8 @@
|
||||
"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.": "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.",
|
||||
"POLL_LOCKED_WARNING": "The administration locked this poll. Votes and comments are frozen, it is no longer possible to participate",
|
||||
"The poll is expired, it will be deleted soon.": "The poll is expired, it will be deleted soon.",
|
||||
"Deletion date:": "Deletion date:"
|
||||
"Deletion date:": "Deletion date:",
|
||||
"Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote."
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "As poll administrator, you can change all the lines of this poll with this button",
|
||||
@ -187,9 +191,12 @@
|
||||
"You are in the poll creation section.": "You are in the poll creation section.",
|
||||
"Required fields cannot be left blank.": "Required fields cannot be left blank.",
|
||||
"Poll title": "Poll title",
|
||||
"Votes cannot be modified.": "Votes cannot be modified",
|
||||
"All voters can modify any vote.": "All voters can modify any vote.",
|
||||
"Voters can modify their vote themselves.": "Voters can modify their vote themselves.",
|
||||
"To receive an email for each new vote.": "To receive an email for each new vote.",
|
||||
"To receive an email for each new comment.": "To receive an email for each new comment.",
|
||||
"Only the poll maker can see the poll's results.": "Only the poll maker can see the poll's results.",
|
||||
"Go to step 2": "Go to step 2"
|
||||
},
|
||||
"Step 2": {
|
||||
@ -298,6 +305,7 @@
|
||||
"Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "Framadate is not properly installed, please check the 'INSTALL' to setup the database before continuing.",
|
||||
"Failed to save poll": "Failed to save poll",
|
||||
"Update vote failed": "Update vote failed",
|
||||
"Adding vote failed": "Adding vote failed"
|
||||
"Adding vote failed": "Adding vote failed",
|
||||
"You can't create a poll with hidden results with the following edition option:": "You can't create a poll with hidden results with the following edition option: "
|
||||
}
|
||||
}
|
@ -111,9 +111,12 @@
|
||||
"Votes and comments are locked": "ES_Les votes et commentaires sont verrouillés",
|
||||
"Votes and comments are open": "ES_Les votes et commentaires sont ouverts",
|
||||
"Votes are editable": "ES_Les votes sont modifiables",
|
||||
"Votes are editable solely by their owner.": "ES_Les votes sont modifiables uniquement par leur créateur",
|
||||
"Save the new rules": "ES_Enregistrer les nouvelles permissions",
|
||||
"Cancel the rules edit": "ES_Annuler le changement de permissions",
|
||||
"The name is invalid.": "ES_Le nom n'est pas valide."
|
||||
"The name is invalid.": "ES_Le nom n'est pas valide.",
|
||||
"Results are hidden.": "ES_Les résultats sont cachés.",
|
||||
"Results are visible.": "ES_Les résultats sont visibles."
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "ES_Votes du sondage",
|
||||
@ -144,7 +147,8 @@
|
||||
"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.": "Para participar a esta encuesta, introduzca su nombre, elige todas las valores que son apriopriadas y validar su seleccion con el botón verde a la fin de línea.",
|
||||
"POLL_LOCKED_WARNING": "ES_L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer",
|
||||
"The poll is expired, it will be deleted soon.": "ES_Le sondage a expiré, il sera bientôt supprimé.",
|
||||
"Deletion date:": "ES_Date de suppression :"
|
||||
"Deletion date:": "ES_Date de suppression :",
|
||||
"Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "ES_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! "
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "En calidad de administrador, Usted puede cambiar todas la líneas de este encuesta con este botón",
|
||||
@ -186,9 +190,12 @@
|
||||
"You are in the poll creation section.": "Usted ha eligiendo de crear une nueva encuesta!",
|
||||
"Required fields cannot be left blank.": "Gracias por completar los campos con una *.",
|
||||
"Poll title": "ES_Titre du sondage",
|
||||
"Voters can modify their vote themselves.": " Los encuentados pueden cambiar su línea ellos mismos.",
|
||||
"To receive an email for each new vote.": " Usted quiere recibir un correo electónico cada vez que alguien participe a la encuesta.",
|
||||
"Votes cannot be modified.": "ES_Aucun vote ne peut être modifié",
|
||||
"All voters can modify any vote.": "ES_Tous les sondés peuvent modifier tous les votes",
|
||||
"Voters can modify their vote themselves.": "Los encuentados pueden cambiar su línea ellos mismos.",
|
||||
"To receive an email for each new vote.": "Usted quiere recibir un correo electónico cada vez que alguien participe a la encuesta.",
|
||||
"To receive an email for each new comment.": "ES_Recevoir un courriel à chaque commentaire.",
|
||||
"Only the poll maker can see the poll's results.": "ES_Seul le créateur du sondage peut voir les résultats.",
|
||||
"Go to step 2": "ES_Aller à l'étape 2"
|
||||
},
|
||||
"Step 2": {
|
||||
@ -297,6 +304,7 @@
|
||||
"Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "ES_Framadate n'est pas installé correctement, lisez le fichier INSTALL pour configurer la base de données avant de continuer.",
|
||||
"Failed to save poll": "ES_Echèc de la sauvegarde du sondage",
|
||||
"Update vote failed": "ES_Mise à jour du vote échoué",
|
||||
"Adding vote failed": "ES_Ajout d'un vote échoué"
|
||||
"Adding vote failed": "ES_Ajout d'un vote échoué",
|
||||
"You can't create a poll with hidden results with the following edition option:": "ES_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : "
|
||||
}
|
||||
}
|
@ -111,9 +111,12 @@
|
||||
"Votes and comments are locked": "Les votes et commentaires sont verrouillés",
|
||||
"Votes and comments are open": "Les votes et commentaires sont ouverts",
|
||||
"Votes are editable": "Les votes sont modifiables",
|
||||
"Votes are editable solely by their owner.": "Les votes sont modifiables uniquement par leur créateur",
|
||||
"Save the new rules": "Enregistrer les nouvelles permissions",
|
||||
"Cancel the rules edit": "Annuler le changement de permissions",
|
||||
"The name is invalid.": "Le nom n'est pas valide."
|
||||
"The name is invalid.": "Le nom n'est pas valide.",
|
||||
"Results are hidden.": "Les résultats sont cachés.",
|
||||
"Results are visible.": "Les résultats sont visibles."
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Votes du sondage",
|
||||
@ -144,7 +147,8 @@
|
||||
"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.": "Pour participer à ce sondage, veuillez entrer votre nom, choisir toutes les valeurs qui vous conviennent et valider votre choix avec le bouton en bout de ligne.",
|
||||
"POLL_LOCKED_WARNING": "L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer",
|
||||
"The poll is expired, it will be deleted soon.": "Le sondage a expiré, il sera bientôt supprimé.",
|
||||
"Deletion date:": "Date de suppression :"
|
||||
"Deletion date:": "Date de suppression :",
|
||||
"Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! "
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton",
|
||||
@ -186,9 +190,12 @@
|
||||
"You are in the poll creation section.": "Vous avez choisi de créer un nouveau sondage.",
|
||||
"Required fields cannot be left blank.": "Merci de remplir les champs obligatoires, marqués d'une *.",
|
||||
"Poll title": "Titre du sondage",
|
||||
"Voters can modify their vote themselves.": "Vous souhaitez que les sondés puissent modifier leur ligne eux-mêmes.",
|
||||
"Votes cannot be modified.": "Aucun vote ne peut être modifié",
|
||||
"All voters can modify any vote.": "Tous les sondés peuvent modifier tous les votes",
|
||||
"Voters can modify their vote themselves.": "Chaque sondé peut modifier son propre vote.",
|
||||
"To receive an email for each new vote.": "Recevoir un courriel à chaque participation d'un sondé.",
|
||||
"To receive an email for each new comment.": "Recevoir un courriel à chaque commentaire.",
|
||||
"Only the poll maker can see the poll's results.": "Seul le créateur du sondage peut voir les résultats.",
|
||||
"Go to step 2": "Aller à l'étape 2"
|
||||
},
|
||||
"Step 2": {
|
||||
@ -297,6 +304,7 @@
|
||||
"Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "Framadate n'est pas installé correctement, lisez le fichier INSTALL pour configurer la base de données avant de continuer.",
|
||||
"Failed to save poll": "Echèc de la sauvegarde du sondage",
|
||||
"Update vote failed": "Mise à jour du vote échoué",
|
||||
"Adding vote failed": "Ajout d'un vote échoué"
|
||||
"Adding vote failed": "Ajout d'un vote échoué",
|
||||
"You can't create a poll with hidden results with the following edition option:": "Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : "
|
||||
}
|
||||
}
|
||||
|
25
studs.php
25
studs.php
@ -22,6 +22,7 @@ use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
@ -93,7 +94,9 @@ function sendUpdateNotification($poll, $mailService, $name, $type) {
|
||||
|
||||
if (!empty($_GET['poll'])) {
|
||||
$poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
if (strlen($poll_id) === 16) {
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$poll) {
|
||||
@ -106,8 +109,8 @@ if (!$poll) {
|
||||
// A vote is going to be edited
|
||||
// -------------------------------
|
||||
|
||||
if (!empty($_POST['edit_vote'])) {
|
||||
$editingVoteId = filter_input(INPUT_POST, 'edit_vote', FILTER_VALIDATE_INT);
|
||||
if (!empty($_GET['vote'])) {
|
||||
$editingVoteId = filter_input(INPUT_GET, 'vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
@ -130,7 +133,13 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
// Update vote
|
||||
$result = $pollService->updateVote($poll_id, $editedVote, $name, $choices);
|
||||
if ($result) {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
if ($poll->editable == Editable::EDITABLE_BY_OWN) {
|
||||
$editedVoteUniqId = filter_input(INPUT_POST, 'edited_vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$urlEditVote = Utils::getUrlSondage($poll_id, false, $editedVoteUniqId);
|
||||
$message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:"), $urlEditVote);
|
||||
} else {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
}
|
||||
sendUpdateNotification($poll, $mailService, $name, UPDATE_VOTE);
|
||||
} else {
|
||||
$message = new Message('danger', _('Update vote failed.'));
|
||||
@ -151,7 +160,12 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
// Add vote
|
||||
$result = $pollService->addVote($poll_id, $name, $choices);
|
||||
if ($result) {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
if ($poll->editable == Editable::EDITABLE_BY_OWN) {
|
||||
$urlEditVote = Utils::getUrlSondage($poll_id, false, $result->uniqId);
|
||||
$message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:"), $urlEditVote);
|
||||
} else {
|
||||
$message = new Message('success', _('Update vote successfully.'));
|
||||
}
|
||||
sendUpdateNotification($poll, $mailService, $name, ADD_VOTE);
|
||||
} else {
|
||||
$message = new Message('danger', _('Update vote failed.'));
|
||||
@ -202,6 +216,7 @@ $smarty->assign('comments', $comments);
|
||||
$smarty->assign('editingVoteId', $editingVoteId);
|
||||
$smarty->assign('message', $message);
|
||||
$smarty->assign('admin', false);
|
||||
$smarty->assign('hidden', $poll->hidden);
|
||||
$smarty->assign('parameter_name_regex', NAME_REGEX);
|
||||
|
||||
$smarty->display('studs.tpl');
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true}" method="POST">
|
||||
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
|
||||
<div class="alert alert-info text-center">
|
||||
<h2>{__('adminstuds', 'Column\'s adding')}</h2>
|
||||
|
||||
|
@ -91,11 +91,11 @@
|
||||
{/if}
|
||||
<td>{$poll->votes|html}</td>
|
||||
<td>{$poll->id|html}</td>
|
||||
<td><a href="{$poll->id|poll_url|html}" class="btn btn-link"
|
||||
<td><a href="{poll_url id=$poll->id}" class="btn btn-link"
|
||||
title="{__('Admin', 'See the poll')}"><span
|
||||
class="glyphicon glyphicon-eye-open"></span><span
|
||||
class="sr-only">{__('Admin', 'See the poll')}</span></a></td>
|
||||
<td><a href="{$poll->admin_id|poll_url:true|html}" class="btn btn-link"
|
||||
<td><a href="{poll_url id=$poll->admin_id admin=true}" class="btn btn-link"
|
||||
title="{__('Admin', 'Change the poll')}"><span
|
||||
class="glyphicon glyphicon-pencil"></span><span
|
||||
class="sr-only">{__('Admin', 'Change the poll')}</span></a></td>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{__('adminstuds', 'Confirm removal of all comments of the poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep the comments')}</button>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{__('adminstuds', 'Confirm removal of the poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep the poll')}</button>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
|
||||
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
|
||||
<div class="alert alert-danger text-center">
|
||||
<h2>{__('adminstuds', 'Confirm removal of all votes of the poll')}</h2>
|
||||
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep votes')}</button>
|
||||
|
@ -1,5 +1,9 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name="header"}
|
||||
<script src="{"js/app/create_poll.js"|resource}" type="text/javascript"></script>
|
||||
{/block}
|
||||
|
||||
{block name=main}
|
||||
<div class="row" style="display:none" id="form-block">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
@ -90,9 +94,17 @@
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type=checkbox name="editable" {if $poll_editable}checked{/if} id="editable">
|
||||
<input type="radio" name="editable" {if empty($poll_editable) or $poll_editable==constant("Framadate\Editable::NOT_EDITABLE")}checked{/if} value="{constant("Framadate\Editable::NOT_EDITABLE")}">
|
||||
{__('Step 1', 'Votes cannot be modified.')}
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="editable" id="editableByAll" {if $poll_editable==constant("Framadate\Editable::EDITABLE_BY_ALL")}checked{/if} value="{constant("Framadate\Editable::EDITABLE_BY_ALL")}">
|
||||
{__('Step 1', 'All voters can modify any vote.')}
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="editable" {if $poll_editable==constant("Framadate\Editable::EDITABLE_BY_OWN")}checked{/if} value="{constant("Framadate\Editable::EDITABLE_BY_OWN")}">
|
||||
{__('Step 1', 'Voters can modify their vote themselves.')}
|
||||
</label>
|
||||
</div>
|
||||
@ -105,7 +117,7 @@
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type=checkbox name="receiveNewVotes" {if $poll_receiveNewVotes}checked{/if}
|
||||
<input type="checkbox" name="receiveNewVotes" {if $poll_receiveNewVotes}checked{/if}
|
||||
id="receiveNewVotes">
|
||||
{__('Step 1', 'To receive an email for each new vote.')}
|
||||
</label>
|
||||
@ -116,13 +128,29 @@
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type=checkbox name="receiveNewComments" {if $poll_receiveNewComments}checked{/if}
|
||||
<input type="checkbox" name="receiveNewComments" {if $poll_receiveNewComments}checked{/if}
|
||||
id="receiveNewComments">
|
||||
{__('Step 1', 'To receive an email for each new comment.')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="hidden" {if $poll_hidden}checked{/if}
|
||||
id="hidden">
|
||||
{__('Step 1', "Only the poll maker can see the poll's results.")}
|
||||
</label>
|
||||
</div>
|
||||
<div id="hiddenWithBadEditionModeError" class="alert alert-danger hidden">
|
||||
<p>
|
||||
{__('Error', "You can't create a poll with hidden results with the following edition option:")}"{__('Step 1', 'All voters can modify any vote.')}"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@ -150,30 +178,4 @@
|
||||
<div id="cookie-warning" class="alert alert-danger" style="display:none">
|
||||
{__('Step 1', 'Cookies are disabled on your browser. Theirs activation is required to create a poll.')}
|
||||
</div>
|
||||
<script>
|
||||
{* TODO Put this in a JS file *}
|
||||
// Check Javascript is enabled, if it is it will execute this script
|
||||
(function () {
|
||||
// Check cookies are enabled too
|
||||
var cookieEnabled = function () {
|
||||
var cookieEnabled = navigator.cookieEnabled;
|
||||
|
||||
// if not IE4+ nor NS6+
|
||||
if (!cookieEnabled && typeof navigator.cookieEnabled === "undefined") {
|
||||
document.cookie = "testcookie";
|
||||
cookieEnabled = document.cookie.indexOf("testcookie") != -1;
|
||||
}
|
||||
|
||||
return cookieEnabled;
|
||||
};
|
||||
|
||||
if (cookieEnabled()) {
|
||||
// Show the form block
|
||||
document.getElementById("form-block").setAttribute("style", "");
|
||||
} else {
|
||||
// Show the warning about cookies
|
||||
document.getElementById("cookie-warning").setAttribute("style", "");
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{/block}
|
@ -51,7 +51,7 @@
|
||||
{if $demo_poll != null}
|
||||
<p>
|
||||
{__('1st section', 'Do you want to')}
|
||||
<a href="{'aqg259dth55iuhwm'|poll_url}">{__('1st section', 'view an example?')}</a>
|
||||
<a href="{poll_url id='aqg259dth55iuhwm'}">{__('1st section', 'view an example?')}</a>
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{$admin = $admin|default:false}
|
||||
|
||||
{if $admin}<form action="{$admin_poll_id|poll_url:true}" method="POST">{/if}
|
||||
{if $admin}<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">{/if}
|
||||
<div class="jumbotron{if $admin} bg-danger{/if}">
|
||||
<div class="row">
|
||||
<div id="title-form" class="col-md-7">
|
||||
@ -90,13 +90,13 @@
|
||||
|
||||
<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}">{__('PollInfo', '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}" />
|
||||
<label for="public-link"><a class="public-link" href="{poll_url id=$poll_id}">{__('PollInfo', '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_url id=$poll_id}" />
|
||||
</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}">{__('PollInfo', '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}" />
|
||||
<label for="admin-link"><a class="admin-link" href="{poll_url id=$admin_poll_id admin=true}">{__('PollInfo', '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="{poll_url id=$admin_poll_id admin=true}" />
|
||||
</div>
|
||||
<div id="expiration-form" class="form-group col-md-4">
|
||||
<h4 class="control-label">{__('PollInfo', 'Expiration date')}</h4>
|
||||
@ -118,14 +118,41 @@
|
||||
</div>
|
||||
{if $admin}
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-8" >
|
||||
<div class="col-md-4 col-md-offset-4" >
|
||||
<div id="poll-hidden-form">
|
||||
{if $poll->hidden}
|
||||
{$hidden_icon = "glyphicon-eye-close"}
|
||||
{$hidden_text = __('PollInfo', 'Results are hidden.')}
|
||||
{else}
|
||||
{$hidden_icon = "glyphicon-eye-open"}
|
||||
{$hidden_text = __('PollInfo', 'Results are visible.')}
|
||||
{/if}
|
||||
<p class=""><span class="glyphicon {$hidden_icon}"> </span> {$hidden_text}<button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the poll rules')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span></button></p>
|
||||
<div class="hidden js-poll-hidden">
|
||||
<div class="input-group">
|
||||
<input type="checkbox" id="hidden" name="hidden" {if $poll->hidden}checked="checked"{/if}/>
|
||||
<label for="hidden">{__('PollInfo', 'Results are hidden.')}</label>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" name="update_poll_info" value="hidden" class="btn btn-success" title="{__('PollInfo', 'Save the new rules')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button>
|
||||
<button class="btn btn-link btn-cancel" title="{__('PollInfo', 'Cancel the rules edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{__('Generic', 'Cancel')}</span></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4" >
|
||||
<div id="poll-rules-form">
|
||||
{if $poll->active}
|
||||
{if $poll->editable}
|
||||
{$rule_id = 2}
|
||||
{if $poll->editable == constant("Framadate\Editable::EDITABLE_BY_ALL")}
|
||||
{$rule_id = 2}
|
||||
{$rule_txt = __('PollInfo', 'Votes are editable')}
|
||||
{else}
|
||||
{$rule_id = 3}
|
||||
{$rule_txt = __('PollInfo', 'Votes are editable solely by their owner.')}
|
||||
{/if}
|
||||
{$rule_icon = '<span class="glyphicon glyphicon-edit"></span>'}
|
||||
{$rule_txt = __('PollInfo', 'Votes are editable')}
|
||||
{else}
|
||||
{else}
|
||||
{$rule_id = 1}
|
||||
{$rule_icon = '<span class="glyphicon glyphicon-check"></span>'}
|
||||
{$rule_txt = __('PollInfo', 'Votes and comments are open')}
|
||||
@ -144,6 +171,7 @@
|
||||
<option value="0"{if $rule_id==0} selected="selected"{/if}>{__('PollInfo', 'Votes and comments are locked')}</option>
|
||||
<option value="1"{if $rule_id==1} selected="selected"{/if}>{__('PollInfo', 'Votes and comments are open')}</option>
|
||||
<option value="2"{if $rule_id==2} selected="selected"{/if}>{__('PollInfo', 'Votes are editable')}</option>
|
||||
<option value="3"{if $rule_id==3} selected="selected"{/if}>{__('PollInfo', 'Votes are editable solely by their owner.')}</option>
|
||||
</select>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" name="update_poll_info" value="rules" class="btn btn-success" title="{__('PollInfo', 'Save the new rules')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button>
|
||||
|
@ -2,10 +2,10 @@
|
||||
{$best_choices = [0]}
|
||||
{/if}
|
||||
|
||||
<h3>{__('Poll results', 'Votes of the poll')}</h3>
|
||||
<h3>{__('Poll results', 'Votes of the poll')} {if $hidden}<i>({__('PollInfo', 'Results are hidden.')})</i>{/if}</h3>
|
||||
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<form action="" method="POST" id="poll_form">
|
||||
<form action="{poll_url id=$poll_id}" method="POST" id="poll_form">
|
||||
<table class="results">
|
||||
<caption class="sr-only">{__('Poll results', 'Votes of the poll')} {$poll->title|html}</caption>
|
||||
<thead>
|
||||
@ -35,11 +35,11 @@
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId == $vote->id}
|
||||
|
||||
{if $editingVoteId === $vote->uniqId}
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group input-group-sm" id="edit">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="hidden" name="edited_vote" value="{$vote->uniqId}"/>
|
||||
<input type="text" id="name" name="name" value="{$vote->name|html}" class="form-control" title="{__('Genric', 'Your name')}" placeholder="{__('Genric', 'Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
@ -50,28 +50,27 @@
|
||||
<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="{__('Poll results', 'Vote yes for')} {$slots[$id]->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')|html} {$slots[$id]->title|html}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Genric', '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="{__('Poll results', 'Vote ifneedbe for')} {$slots[$id]->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slots[$id]->title|html}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Genric', '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="{__('Poll results', 'Vote no for')} {$slots[$id]->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slots[$id]->title|html}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Genric', 'No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs check-name" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{else}
|
||||
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{elseif !$hidden}
|
||||
{* Voted line *}
|
||||
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
@ -88,13 +87,13 @@
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && $poll->editable && !$expired}
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<td>
|
||||
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{__('Poll results', 'Edit the line:')} {$vote->name|html}">
|
||||
<a href="{poll_url id=$poll->id vote_id=$vote->uniqId}" class="btn btn-link btn-sm" title="{__('Poll results', 'Edit the line:')|html} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</button>
|
||||
</a>
|
||||
{if $admin}
|
||||
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')|html} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
</button>
|
||||
{/if}
|
||||
@ -108,7 +107,7 @@
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId == 0 && !$expired}
|
||||
{if $active && $editingVoteId === 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
@ -121,78 +120,81 @@
|
||||
<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="{__('Poll results', 'Vote yes for')} {$slot->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')|html} {$slot->title|html}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', '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="{__('Poll results', 'Vote ifneedbe for')} {$slot->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slot->title|html}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', '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="{__('Poll results', 'Vote no for')} {$slot->title|html}">
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slot->title|html}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Generic', 'No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td><button type="submit" class="btn btn-success btn-md check-name" name="save" title="{__('Poll results', 'Save the choices')}">{__('Generic', 'Save')}</button></td>
|
||||
<td><button type="submit" class="btn btn-success btn-md" name="save" title="{__('Poll results', 'Save the choices')}">{__('Generic', 'Save')}</button></td>
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{__('Poll results', '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>
|
||||
{elseif $best_choice > 0}
|
||||
<td>{$best_choice|html}</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{if !$hidden}
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{__('Poll results', '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>
|
||||
{elseif $best_choice > 0}
|
||||
<td>{$best_choice|html}</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{/if}
|
||||
{/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>{__('Poll results', '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>{__('Poll results', 'The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', 'Best choices')}</h3></div>
|
||||
{if !$hidden}
|
||||
{* Best votes listing *}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<div class="row">
|
||||
{if $count_bests == 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', '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>{__('Poll results', 'The bests choices at this time are:')}</p>
|
||||
{/if}
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{__('Poll results', 'The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', '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>{__('Poll results', '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>{__('Generic', 'with')} <b>{$max|html}</b> {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.</p>
|
||||
{$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>{__('Generic', 'with')} <b>{$max|html}</b> {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
@ -2,10 +2,10 @@
|
||||
{$best_choices = [0]}
|
||||
{/if}
|
||||
|
||||
<h3>{__('Poll results', 'Votes of the poll')}</h3>
|
||||
<h3>{__('Poll results', 'Votes of the poll')} {if $hidden}<i>({__('PollInfo', 'Results are hidden.')})</i>{/if}</h3>
|
||||
|
||||
<div id="tableContainer" class="tableContainer">
|
||||
<form action="" method="POST" id="poll_form">
|
||||
<form action="{poll_url id=$poll_id}" method="POST" id="poll_form">
|
||||
<table class="results">
|
||||
<caption class="sr-only">{__('Poll results', 'Votes of the poll')} {$poll->title|html}</caption>
|
||||
<thead>
|
||||
@ -81,11 +81,11 @@
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId == $vote->id && !$expired}
|
||||
|
||||
{if $editingVoteId === $vote->uniqId && !$expired}
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group input-group-sm" id="edit">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
<input type="hidden" name="edited_vote" value="{$vote->uniqId}"/>
|
||||
<input type="text" id="name" name="name" value="{$vote->name|html}" class="form-control" title="{__('Generic', 'Your name')}" placeholder="{__('Generic', 'Your name')}" />
|
||||
</div>
|
||||
</td>
|
||||
@ -115,8 +115,8 @@
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs check-name" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{else}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{elseif !$hidden}
|
||||
|
||||
{* Voted line *}
|
||||
|
||||
@ -134,11 +134,11 @@
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && $poll->editable && !$expired}
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<td>
|
||||
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{__('Poll results', 'Edit the line:')} {$vote->name|html}">
|
||||
<a href="{poll_url id=$poll->id vote_id=$vote->uniqId}" class="btn btn-link btn-sm" title="{__('Poll results', 'Edit the line:')|escape} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</button>
|
||||
</a>
|
||||
{if $admin}
|
||||
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
@ -154,7 +154,7 @@
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId == 0 && !$expired}
|
||||
{if $active && $editingVoteId === 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
@ -190,61 +190,64 @@
|
||||
{$i = $i+1}
|
||||
{/foreach}
|
||||
{/foreach}
|
||||
<td><button type="submit" class="btn btn-success btn-md check-name" name="save" title="{__('Poll results', 'Save the choices')}">{__('Generic', 'Save')}</button></td>
|
||||
<td><button type="submit" class="btn btn-success btn-md" name="save" title="{__('Poll results', 'Save the choices')}">{__('Generic', 'Save')}</button></td>
|
||||
</tr>
|
||||
{/if}
|
||||
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{__('Poll results', '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>
|
||||
{elseif $best_moment > 0}
|
||||
<td>{$best_moment|html}</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{if !$hidden}
|
||||
{* Line displaying best moments *}
|
||||
{$count_bests = 0}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<tr id="addition">
|
||||
<td>{__('Poll results', '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>
|
||||
{elseif $best_moment > 0}
|
||||
<td>{$best_moment|html}</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tr>
|
||||
{/if}
|
||||
{/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>{__('Poll results', '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>{__('Poll results', 'The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', 'Best choices')}</h3></div>
|
||||
{if !$hidden}
|
||||
{* Best votes listing *}
|
||||
{$max = max($best_choices)}
|
||||
{if $max > 0}
|
||||
<div class="row">
|
||||
{if $count_bests == 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', '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>{__('Poll results', 'The bests choices at this time are:')}</p>
|
||||
{/if}
|
||||
<p><span class="glyphicon glyphicon-star text-warning"></span>{__('Poll results', 'The best choice at this time is:')}</p>
|
||||
{elseif $count_bests > 1}
|
||||
<div class="col-sm-12"><h3>{__('Poll results', '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>{__('Poll results', '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}
|
||||
{$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}
|
||||
{/foreach}
|
||||
</ul>
|
||||
<p>{__('Generic', 'with')} <b>{$max|html}</b> {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.</p>
|
||||
</ul>
|
||||
<p>{__('Generic', 'with')} <b>{$max|html}</b> {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
@ -9,7 +9,7 @@
|
||||
|
||||
<div id="message-container">
|
||||
{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>
|
||||
<div class="alert alert-dismissible alert-{$message->type|html}" role="alert">{$message->message|html}{if $message->link != null}<br/><a href="{$message->link}">{$message->link}</a>{/if}<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>
|
||||
{/if}
|
||||
</div>
|
||||
<div id="nameErrorMessage" class="hidden alert alert-dismissible alert-danger" role="alert">{__('PollInfo', 'The name is invalid.')}<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>
|
||||
|
Loading…
Reference in New Issue
Block a user