Merge branch 'feature/improve-self-editing-vote' into 'develop'
Feature : improve self editing vote Adding a possibility to the user to enter his email address and to receive the personalized url by email. See merge request !110
This commit is contained in:
commit
ab0748597a
@ -23,8 +23,6 @@ use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
|
96
action/send_edit_link_by_email_action.php
Normal file
96
action/send_edit_link_by_email_action.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?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\SessionService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
$logService = new LogService();
|
||||
$sessionService = new SessionService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
$pollService = new PollService($connect, $logService);
|
||||
|
||||
$result = false;
|
||||
$message = null;
|
||||
$poll = null;
|
||||
$poll_id = null;
|
||||
$email = null;
|
||||
|
||||
if (!empty($_POST['poll'])) {
|
||||
$poll_id = filter_input(INPUT_POST, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$poll = $pollService->findById($poll_id);
|
||||
}
|
||||
|
||||
$token = $sessionService->get("Common", SESSION_EDIT_LINK_TOKEN);
|
||||
$token_form_value = empty($_POST['token']) ? null : $_POST['token'];
|
||||
$editedVoteUniqueId = filter_input(INPUT_POST, 'editedVoteUniqueId', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
if (is_null($poll) || $config['use_smtp'] == false || is_null($token) || is_null($token_form_value)
|
||||
|| !$token->check($token_form_value) || is_null($editedVoteUniqueId)) {
|
||||
$message = new Message('error', __('Error', 'Something is going wrong...'));
|
||||
}
|
||||
|
||||
if (is_null($message)) {
|
||||
$email = $mailService->isValidEmail($_POST['email']);
|
||||
if (is_null($email)) {
|
||||
$message = new Message('error', __('EditLink', 'The email address is not correct.'));
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($message)) {
|
||||
$time = $sessionService->get("Common", SESSION_EDIT_LINK_TIME);
|
||||
|
||||
if (!empty($time)) {
|
||||
$remainingTime = TIME_EDIT_LINK_EMAIL - (time() - $time);
|
||||
|
||||
if ($remainingTime > 0) {
|
||||
$message = new Message('error', __f('EditLink', 'Please wait %d seconds before we can send an email to you then try again.', $remainingTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (is_null($message)) {
|
||||
$url = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
|
||||
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('editedVoteUniqueId', $editedVoteUniqueId);
|
||||
$body = $smarty->fetch('mail/remember_edit_link.tpl');
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . ']['.__('EditLink', 'REMINDER').'] '.__f('EditLink', 'Edit link for poll "%s"', $poll->title);
|
||||
|
||||
//$mailService->send($email, $subject, $body);
|
||||
$sessionService->remove("Common", SESSION_EDIT_LINK_TOKEN);
|
||||
$sessionService->set("Common", SESSION_EDIT_LINK_TIME, time());
|
||||
|
||||
$message = new Message('success', __('EditLink', 'Your reminder has been successfully sent!'));
|
||||
$result = true;
|
||||
}
|
||||
|
||||
$smarty->error_reporting = E_ALL & ~E_NOTICE;
|
||||
|
||||
$response = array('result' => $result, 'message' => $message);
|
||||
|
||||
|
||||
echo json_encode($response);
|
@ -23,11 +23,17 @@ class Message {
|
||||
var $type;
|
||||
var $message;
|
||||
var $link;
|
||||
var $linkTitle;
|
||||
var $linkIcon;
|
||||
var $includeTemplate;
|
||||
|
||||
function __construct($type, $message, $link=null) {
|
||||
function __construct($type, $message, $link=null, $linkTitle=null, $linkIcon=null, $includeTemplate=null) {
|
||||
$this->type = $type;
|
||||
$this->message = $message;
|
||||
$this->link = $link;
|
||||
$this->linkTitle = $linkTitle;
|
||||
$this->linkIcon = $linkIcon;
|
||||
$this->includeTemplate = $includeTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,12 +3,13 @@ namespace Framadate\Security;
|
||||
|
||||
class Token {
|
||||
|
||||
const DEFAULT_LENGTH = 64;
|
||||
private $time;
|
||||
private $value;
|
||||
private $length;
|
||||
private static $codeAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
|
||||
|
||||
function __construct($length = 64) {
|
||||
function __construct($length = self::DEFAULT_LENGTH) {
|
||||
$this->length = $length;
|
||||
$this->time = time() + TOKEN_TIME;
|
||||
$this->value = $this->generate();
|
||||
@ -41,7 +42,7 @@ class Token {
|
||||
* @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) {
|
||||
public static function getToken($length = self::DEFAULT_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);
|
||||
|
@ -44,6 +44,19 @@ class SessionService {
|
||||
$_SESSION[$section][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a session value
|
||||
*
|
||||
* @param $section
|
||||
* @param $key
|
||||
*/
|
||||
public function remove($section, $key) {
|
||||
assert(!empty($key));
|
||||
assert(!empty($section));
|
||||
|
||||
unset($_SESSION[$section][$key]);
|
||||
}
|
||||
|
||||
private function initSectionIfNeeded($section) {
|
||||
if (!isset($_SESSION[$section])) {
|
||||
$_SESSION[$section] = array();
|
||||
|
@ -77,6 +77,9 @@ const PURGE_DELAY = 60;
|
||||
// Max slots per poll
|
||||
const MAX_SLOTS_PER_POLL = 366;
|
||||
|
||||
// Number of seconds before we allow to resend an "Remember Edit Link" email.
|
||||
const TIME_EDIT_LINK_EMAIL = 60;
|
||||
|
||||
// Config
|
||||
$config = [
|
||||
/* general config */
|
||||
|
@ -30,5 +30,9 @@ const EDITABLE_CHOICE_REGEX = '/^[0-2]$/';
|
||||
const BASE64_REGEX = '/^[A-Za-z0-9]+$/';
|
||||
const MD5_REGEX = '/^[A-Fa-f0-9]{32}$/';
|
||||
|
||||
// Session constants
|
||||
const SESSION_EDIT_LINK_TOKEN = 'EditLinkToken';
|
||||
const SESSION_EDIT_LINK_TIME = "EditLinkMail";
|
||||
|
||||
// CSRF (300s = 5min)
|
||||
const TOKEN_TIME = 300;
|
||||
|
@ -136,7 +136,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Stimmabgaben zur Umfrage",
|
||||
"Edit the line:": "Zeile bearbeiten:",
|
||||
"Edit the line: %s": "Zeile bearbeiten: %s",
|
||||
"Remove the line:": "Zeile entfernen:",
|
||||
"Vote no for": "Nein-Stimmen für",
|
||||
"Vote yes for": "Ja-Stimmen für",
|
||||
@ -179,6 +179,16 @@
|
||||
"Update vote succeeded": "Die Wertung wurde geändert",
|
||||
"Adding the vote succeeded": "Die Wertung wurde hinzugefügt"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "DE_Envoyer",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "DE_Afin de ne pas perdre ce lien d'édition de vote, nous pouvons vous l'envoyer par courriel.",
|
||||
"The email address is not correct.": "DE_Courriel incorrect.",
|
||||
"REMINDER": "DE_RAPPEL",
|
||||
"Edit link for poll \"%s\"": "DE_Lien d'édition du sondage \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "DE_Veuillez patienter encore %d seconds avant que nous puissions vous envoyer un email, puis réessayez.",
|
||||
"Here is the link for editing your vote:": "DE_Voici le lien pour éditer votre vote :",
|
||||
"Your reminder has been successfully sent!": "DE_Votre rappel a été envoyé avec succès !"
|
||||
},
|
||||
"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",
|
||||
"remove a column or a line with": "Zeile oder Spalte entfernen mit",
|
||||
|
@ -136,7 +136,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Votes",
|
||||
"Edit the line:": "Edit line:",
|
||||
"Edit the line: %s": "Edit line: %s",
|
||||
"Remove the line:": "Remove line:",
|
||||
"Vote no for": "Vote \"no\" for",
|
||||
"Vote yes for": "Vote \"yes\" for",
|
||||
@ -179,6 +179,16 @@
|
||||
"Update vote succeeded": "Vote updated",
|
||||
"Adding the vote succeeded": "Vote added"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "Send",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "If you don't want to lose your personalized link, we can send it to your email.",
|
||||
"The email address is not correct.": "The email address is not correct.",
|
||||
"REMINDER": "REMINDER",
|
||||
"Edit link for poll \"%s\"": "Edit link for poll \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "Please wait %d seconds before we can send an email to you then try again.",
|
||||
"Here is the link for editing your vote:": "Here is the link for editing your vote:",
|
||||
"Your reminder has been successfully sent!": "Your reminder has been successfully sent!"
|
||||
},
|
||||
"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",
|
||||
"remove a column or a line with": "remove a column or a line with",
|
||||
|
@ -139,7 +139,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Votos de la encuesta",
|
||||
"Edit the line:": "Modificar la fila:",
|
||||
"Edit the line: %s": "Modificar la fila: %s",
|
||||
"Remove the line:": "Borrar la fila:",
|
||||
"Vote no for": "Votar « no » para",
|
||||
"Vote yes for": "Votar « si » para",
|
||||
@ -182,6 +182,16 @@
|
||||
"Update vote succeeded": "Actualización exítosa de su voto",
|
||||
"Adding the vote succeeded": "Voto guardado con exíto"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "ES_Envoyer",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "ES_Afin de ne pas perdre ce lien d'édition de vote, nous pouvons vous l'envoyer par courriel.",
|
||||
"The email address is not correct.": "ES_Courriel incorrect.",
|
||||
"REMINDER": "ES_RAPPEL",
|
||||
"Edit link for poll \"%s\"": "ES_Lien d'édition du sondage \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "ES_Veuillez patienter encore %d seconds avant que nous puissions vous envoyer un email, puis réessayez.",
|
||||
"Here is the link for editing your vote:": "ES_Voici le lien pour éditer votre vote :",
|
||||
"Your reminder has been successfully sent!": "ES_Votre rappel a été envoyé avec succès !"
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "Como administrador, Usted puede cambiar todas las filas de la encuesta con este botón",
|
||||
"remove a column or a line with": "borrar una columna o una fila con",
|
||||
|
@ -136,7 +136,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Votes du sondage",
|
||||
"Edit the line:": "Modifier la ligne :",
|
||||
"Edit the line: %s": "Modifier la ligne : %s",
|
||||
"Remove the line:": "Supprimer la ligne :",
|
||||
"Vote no for": "Voter « non » pour",
|
||||
"Vote yes for": "Voter « oui » pour",
|
||||
@ -179,6 +179,16 @@
|
||||
"Update vote succeeded": "Mise à jour du vote réussi",
|
||||
"Adding the vote succeeded": "Ajout du vote réussi"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "Envoyer",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "Afin de ne pas perdre ce lien d'édition de vote, nous pouvons vous l'envoyer par courriel.",
|
||||
"The email address is not correct.": "Courriel incorrect.",
|
||||
"REMINDER": "RAPPEL",
|
||||
"Edit link for poll \"%s\"": "Lien d'édition du sondage \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "Veuillez patienter encore %d secondes avant que nous puissions vous envoyer un email, puis réessayez.",
|
||||
"Here is the link for editing your vote:": "Voici le lien pour éditer votre vote :",
|
||||
"Your reminder has been successfully sent!": "Votre rappel a été envoyé avec succès !"
|
||||
},
|
||||
"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",
|
||||
"remove a column or a line with": "effacer une colonne ou une ligne avec",
|
||||
|
@ -136,7 +136,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Voti del sondaggio ",
|
||||
"Edit the line:": "Modificare la riga :",
|
||||
"Edit the line: %s": "Modificare la riga : %s",
|
||||
"Remove the line:": "Eliminare la riga :",
|
||||
"Vote no for": "Scegliere \"no\" per",
|
||||
"Vote yes for": "Scegliere \"sì\" per",
|
||||
@ -179,6 +179,16 @@
|
||||
"Update vote succeeded": "Aggiornamento del voto di successo",
|
||||
"Adding the vote succeeded": "L'aggiunta del voto ha avuto successo"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "IT_Envoyer",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "IT_Afin de ne pas perdre ce lien d'édition de vote, nous pouvons vous l'envoyer par courriel.",
|
||||
"The email address is not correct.": "IT_Courriel incorrect.",
|
||||
"REMINDER": "IT_RAPPEL",
|
||||
"Edit link for poll \"%s\"": "IT_Lien d'édition du sondage \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "IT_Veuillez patienter encore %d seconds avant que nous puissions vous envoyer un email, puis réessayez.",
|
||||
"Here is the link for editing your vote:": "IT_Voici le lien pour éditer votre vote :",
|
||||
"Your reminder has been successfully sent!": "IT_Votre rappel a été envoyé avec succès !"
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "Essendo l'amministratore, potete modificare tutte le righe di questo sondaggio con questo pulsante",
|
||||
"remove a column or a line with": " cancellare una colonna o una riga con ",
|
||||
|
@ -134,7 +134,7 @@
|
||||
},
|
||||
"Poll results": {
|
||||
"Votes of the poll": "Vòtes del sondatge",
|
||||
"Edit the line:": "Modificar la linha :",
|
||||
"Edit the line: %s": "Modificar la linha : %s",
|
||||
"Remove the line:": "Suprimir la linha :",
|
||||
"Vote no for": "Votar « non » per",
|
||||
"Vote yes for": "Votar « òc » per",
|
||||
@ -170,6 +170,16 @@
|
||||
"Update vote succeeded": "Mesa a jorn del vòte amb succès",
|
||||
"Adding the vote succeeded": "Apondon del vòte capitat"
|
||||
},
|
||||
"EditLink": {
|
||||
"Send": "OC_Envoyer",
|
||||
"If you don't want to lose your personalized link, we can send it to your email.": "OC_Afin de ne pas perdre ce lien d'édition de vote, nous pouvons vous l'envoyer par courriel.",
|
||||
"The email address is not correct.": "OC_Courriel incorrect.",
|
||||
"REMINDER": "OC_RAPPEL",
|
||||
"Edit link for poll \"%s\"": "OC_Lien d'édition du sondage \"%s\"",
|
||||
"Please wait %d seconds before we can send an email to you then try again.": "OC_Veuillez patienter encore %d seconds avant que nous puissions vous envoyer un email, puis réessayez.",
|
||||
"Here is the link for editing your vote:": "OC_Voici le lien pour éditer votre vote :",
|
||||
"Your reminder has been successfully sent!": "OC_Votre rappel a été envoyé avec succès !"
|
||||
},
|
||||
"adminstuds": {
|
||||
"As poll administrator, you can change all the lines of this poll with this button": "En qualitat d'administrator podètz modificar totas las linhas d'aqueste sondatge amb aqueste boton",
|
||||
"remove a column or a line with": "escafar una colomna o una linha amb",
|
||||
|
31
studs.php
31
studs.php
@ -28,6 +28,7 @@ use Framadate\Services\SessionService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
use Framadate\Editable;
|
||||
use Framadate\Security\Token;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
@ -139,9 +140,7 @@ if ($accessGranted) {
|
||||
if ($result) {
|
||||
if ($poll->editable == Editable::EDITABLE_BY_OWN) {
|
||||
$editedVoteUniqueId = filter_input(INPUT_POST, 'edited_vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
|
||||
$sessionService->set(USER_REMEMBER_VOTES_KEY, $poll_id, $editedVoteUniqueId);
|
||||
$urlEditVote = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
|
||||
$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);
|
||||
$message = getMessageForOwnVoteEditableVote($sessionService, $smarty, $editedVoteUniqueId, $config['use_smtp'], $poll_id, $name);
|
||||
} else {
|
||||
$message = new Message('success', __('studs', 'Update vote succeeded'));
|
||||
}
|
||||
@ -172,9 +171,7 @@ if ($accessGranted) {
|
||||
if ($result) {
|
||||
if ($poll->editable == Editable::EDITABLE_BY_OWN) {
|
||||
$editedVoteUniqueId = $result->uniqId;
|
||||
$sessionService->set(USER_REMEMBER_VOTES_KEY, $poll_id, $editedVoteUniqueId);
|
||||
$urlEditVote = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
|
||||
$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);
|
||||
$message = getMessageForOwnVoteEditableVote($sessionService, $smarty, $editedVoteUniqueId, $config['use_smtp'], $poll_id, $name);
|
||||
} else {
|
||||
$message = new Message('success', __('studs', 'Adding the vote succeeded'));
|
||||
}
|
||||
@ -191,6 +188,28 @@ if ($accessGranted) {
|
||||
}
|
||||
}
|
||||
|
||||
// Functions
|
||||
function getMessageForOwnVoteEditableVote(SessionService &$sessionService, Smarty &$smarty, $editedVoteUniqueId, $canUseSMTP, $poll_id, $name) {
|
||||
$sessionService->set(USER_REMEMBER_VOTES_KEY, $poll_id, $editedVoteUniqueId);
|
||||
$urlEditVote = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
|
||||
$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,
|
||||
__f('Poll results', 'Edit the line: %s', $name),
|
||||
'glyphicon-pencil');
|
||||
if ($canUseSMTP) {
|
||||
$token = new Token();
|
||||
$sessionService->set("Common", SESSION_EDIT_LINK_TOKEN, $token);
|
||||
$smarty->assign('editedVoteUniqueId', $editedVoteUniqueId);
|
||||
$smarty->assign('token', $token->getValue());
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$message->includeTemplate = $smarty->fetch('part/form_remember_edit_link.tpl');
|
||||
$smarty->clearAssign('token');
|
||||
}
|
||||
return $message;
|
||||
}
|
||||
|
||||
// Retrieve data
|
||||
if ($resultPubliclyVisible || $accessGranted) {
|
||||
$slots = $pollService->allSlotsByPoll($poll);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{block name=main}
|
||||
{if !empty($message)}
|
||||
<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="{__('Generic', '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="{__('Generic', 'Close')}"><span aria-hidden="true">×</span></button></div>
|
||||
{/if}
|
||||
<form action="" method="post">
|
||||
<div class="row">
|
||||
|
5
tpl/mail/remember_edit_link.tpl
Normal file
5
tpl/mail/remember_edit_link.tpl
Normal file
@ -0,0 +1,5 @@
|
||||
<h1>{$poll->title|html|string_format:__('EditLink', 'Edit link for poll "%s"')}</h1>
|
||||
<p>
|
||||
{__('EditLink', 'Here is the link for editing your vote:')}
|
||||
<a href="{poll_url id=$poll->admin_id vote_id=$editedVoteUniqueId}">{$poll->title|html}</a>
|
||||
</p>
|
57
tpl/part/form_remember_edit_link.tpl
Normal file
57
tpl/part/form_remember_edit_link.tpl
Normal file
@ -0,0 +1,57 @@
|
||||
<div class="well">
|
||||
<form action="action/send_edit_link_by_email_action.php" method="POST" class="form-inline" id="send_edit_link_form">
|
||||
<p>{__('EditLink', "If you don't want to lose your personalized link, we can send it to your email.")}</p>
|
||||
<input type="hidden" name="token" value="{$token}"/>
|
||||
<input type="hidden" name="poll" value="{$poll_id}"/>
|
||||
<input type="hidden" name="editedVoteUniqueId" value="{$editedVoteUniqueId}"/>
|
||||
<div class="form-group">
|
||||
<label for="email" class="control-label">{__('PollInfo', 'Email')}</label>
|
||||
<input type="email" name="email" id="email" class="form-control" />
|
||||
<input type="submit" id="send_edit_link_submit" value="{__('EditLink', 'Send')}" class="btn btn-success">
|
||||
</div>
|
||||
</form>
|
||||
<div id="send_edit_link_alert"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
var form = $('#send_edit_link_form');
|
||||
form.submit(function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
if ($('#email').val()) {
|
||||
//$('#send_edit_link_submit').attr("disabled", "disabled");
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: form.attr('action'),
|
||||
data: form.serialize(),
|
||||
dataType: 'json',
|
||||
success: function(data)
|
||||
{
|
||||
var newMessage;
|
||||
if (data.result) {
|
||||
$('#send_edit_link_form').remove();
|
||||
newMessage = $('#genericUnclosableSuccessTemplate').clone();
|
||||
} else {
|
||||
newMessage = $('#genericErrorTemplate').clone();
|
||||
}
|
||||
newMessage
|
||||
.find('.contents')
|
||||
.text(data.message.message);
|
||||
newMessage.removeClass('hidden');
|
||||
$('#send_edit_link_alert')
|
||||
.empty()
|
||||
.append(newMessage);
|
||||
},
|
||||
complete: function() {
|
||||
$('#add_comment').removeAttr("disabled");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
@ -128,7 +128,7 @@
|
||||
}
|
||||
|
||||
<td class="hidden-print">
|
||||
<a href="{if $admin}{poll_url id=$poll->admin_id vote_id=$vote->uniqId admin=true}{else}{poll_url id=$poll->id vote_id=$vote->uniqId}{/if}" class="btn btn-default btn-sm" title="{__('Poll results', 'Edit the line:')|html} {$vote->name|html}">
|
||||
<a href="{if $admin}{poll_url id=$poll->admin_id vote_id=$vote->uniqId admin=true}{else}{poll_url id=$poll->id vote_id=$vote->uniqId}{/if}" class="btn btn-default btn-sm" title="{__f('Poll results', 'Edit the line: %s', $vote->name)|html}">
|
||||
<i class="glyphicon glyphicon-pencil"></i><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
|
@ -177,7 +177,7 @@
|
||||
)
|
||||
}
|
||||
<td class="hidden-print">
|
||||
<a href="{if $admin}{poll_url id=$poll->admin_id vote_id=$vote->uniqId admin=true}{else}{poll_url id=$poll->id vote_id=$vote->uniqId}{/if}" class="btn btn-default btn-sm" title="{__('Poll results', 'Edit the line:')|escape} {$vote->name|html}">
|
||||
<a href="{if $admin}{poll_url id=$poll->admin_id vote_id=$vote->uniqId admin=true}{else}{poll_url id=$poll->id vote_id=$vote->uniqId}{/if}" class="btn btn-default btn-sm" title="{__f('Poll results', 'Edit the line: %s', $vote->name)|html}">
|
||||
<i class="glyphicon glyphicon-pencil"></i><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
|
@ -15,11 +15,28 @@
|
||||
{* Messages *}
|
||||
<div id="message-container">
|
||||
{if !empty($message)}
|
||||
<div class="alert alert-dismissible alert-{$message->type|html} hidden-print" 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="{__('Generic', 'CLose')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div class="alert alert-dismissible alert-{$message->type|html} hidden-print" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">×</span></button>
|
||||
{$message->message|html}
|
||||
{if $message->link != null}
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-btn">
|
||||
<a {if $message->linkTitle != null} title="{$message->linkTitle|escape}" {/if} class="btn btn-default btn-sm" href="{$message->link}">
|
||||
{if $message->linkIcon != null}<i class="glyphicon glyphicon-pencil"></i>{if $message->linkTitle != null}<span class="sr-only">{$message->linkTitle|escape}</span>{/if}{/if}
|
||||
</a>
|
||||
</span>
|
||||
<input type="text" aria-hidden="true" value="{$message->link}" class="form-control" readonly="readonly" >
|
||||
</div>
|
||||
{if $message->includeTemplate != null}
|
||||
{$message->includeTemplate}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div id="nameErrorMessage" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert">{__('Error', 'The name is invalid.')}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'CLose')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div id="genericErrorTemplate" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert"><span class="contents"></span><button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'CLose')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div id="nameErrorMessage" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert">{__('Error', 'The name is invalid.')}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div id="genericErrorTemplate" class="hidden alert alert-dismissible alert-danger hidden-print" role="alert"><span class="contents"></span><button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">×</span></button></div>
|
||||
<div id="genericUnclosableSuccessTemplate" class="hidden alert alert-success hidden-print" role="alert"><span class="contents"></span></div>
|
||||
|
||||
{if !$accessGranted && !$resultPubliclyVisible}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user