Merge branch 'release/0.9' into develop
This commit is contained in:
commit
9ef15cc4e7
@ -18,6 +18,7 @@
|
||||
- Amélioration : Mise à jour des fichiers .md pour faciliter la collaboration
|
||||
- Amélioration : Le nom de l'auteur et la date d'expiration sont modifiables
|
||||
- Amélioration : Le nom de vote est modifiable
|
||||
- Amélioration : Affichage du comptage des "Si nécessaire" entre parenthèses
|
||||
- Fix : Purge en 2 étapes → 1. Verrouillage du sondage → 2. 60 jours plus tard suppression du sondage
|
||||
- Fix : Date d'expiration qui devient nulle quand on ajoute une colonne
|
||||
- Fix : clic/focus sur oui/non/si nécessaire → retour à gauche de la barre de scroll sur Chromium
|
||||
|
@ -21,7 +21,6 @@ use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
include_once __DIR__ . '/../bandeaux.php';
|
||||
|
@ -16,15 +16,22 @@
|
||||
* 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\PollService;
|
||||
use Framadate\Editable;
|
||||
use Framadate\Message;
|
||||
use Framadate\Services\AdminPollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Editable;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Constants */
|
||||
/* --------- */
|
||||
const UPDATE_POLL = 1;
|
||||
const DELETED_POLL = 2;
|
||||
|
||||
/* Variables */
|
||||
/* --------- */
|
||||
|
||||
@ -41,6 +48,41 @@ $logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp']);
|
||||
|
||||
/* Functions */
|
||||
/*-----------*/
|
||||
|
||||
/**
|
||||
* Send a notification to the poll admin to notify him about an update.
|
||||
*
|
||||
* @param stdClass $poll The poll
|
||||
* @param MailService $mailService The mail service
|
||||
* @param int $type cf: Constants on the top of this page
|
||||
*/
|
||||
function sendUpdateNotification($poll, $mailService, $type) {
|
||||
if (!isset($_SESSION['mail_sent'])) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
if ($poll->receiveNewVotes) {
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __('Mail', 'Notification of poll') . ' : ' . $poll->title;
|
||||
|
||||
$message = '';
|
||||
switch ($type) {
|
||||
case UPDATE_POLL:
|
||||
$message = __f('Mail', 'Someone just change your poll available at the following link %s.', Utils::getUrlSondage($poll->admin_id, true)) . "\n\n";
|
||||
break;
|
||||
case DELETED_POLL:
|
||||
$message = __f('Mail', 'Someone just delete your poll %s.', Utils::htmlEscape($poll->title)) . "\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
}
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
@ -111,7 +153,8 @@ if (isset($_POST['update_poll_info'])) {
|
||||
break;
|
||||
}
|
||||
} elseif ($field == 'expiration_date') {
|
||||
$expiration_date = filter_input(INPUT_POST, 'expiration_date', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]+[-/][0-9]+[-/][0-9]+#']]);
|
||||
$expiration_date = filter_input(INPUT_POST, 'expiration_date', FILTER_VALIDATE_REGEXP,
|
||||
['options' => ['regexp' => '#^[0-9]{4}-[0-9]{2}-[0-9]{2}$#']]);
|
||||
if ($expiration_date) {
|
||||
$poll->end_date = $expiration_date;
|
||||
$updated = true;
|
||||
@ -133,6 +176,7 @@ if (isset($_POST['update_poll_info'])) {
|
||||
// Update poll in database
|
||||
if ($updated && $adminPollService->updatePoll($poll)) {
|
||||
$message = new Message('success', __('adminstuds', 'Poll saved'));
|
||||
sendUpdateNotification($poll, $mailService, UPDATE_POLL);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to save poll'));
|
||||
$poll = $pollService->findById($poll_id);
|
||||
@ -297,6 +341,7 @@ if (isset($_POST['delete_poll'])) {
|
||||
if (isset($_POST['confirm_delete_poll'])) {
|
||||
if ($adminPollService->deleteEntirePoll($poll_id)) {
|
||||
$message = new Message('success', __('adminstuds', 'Poll fully deleted'));
|
||||
sendUpdateNotification($poll, $mailService, DELETED_POLL);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to delete the poll'));
|
||||
}
|
||||
@ -322,15 +367,15 @@ if (!empty($_GET['delete_column'])) {
|
||||
$slot->title = $ex[0];
|
||||
$slot->moment = $ex[1];
|
||||
|
||||
$result = $adminPollService->deleteDateSlot($poll_id, $slot);
|
||||
$result = $adminPollService->deleteDateSlot($poll, $slot);
|
||||
} else {
|
||||
$result = $adminPollService->deleteClassicSlot($poll_id, $column);
|
||||
$result = $adminPollService->deleteClassicSlot($poll, $column);
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$message = new Message('success', __('adminstuds', 'Column removed'));
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to delete the column'));
|
||||
$message = new Message('danger', __('Error', 'Failed to delete column'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,10 +397,10 @@ if (isset($_POST['confirm_add_slot'])) {
|
||||
$newmoment = strip_tags($_POST['newmoment']);
|
||||
|
||||
$ex = explode('/', $newdate);
|
||||
$result = $adminPollService->addSlot($poll_id, mktime(0, 0, 0, $ex[1], $ex[0], $ex[2]), $newmoment);
|
||||
$result = $adminPollService->addDateSlot($poll_id, mktime(0, 0, 0, $ex[1], $ex[0], $ex[2]), $newmoment);
|
||||
} else {
|
||||
$newslot = strip_tags($_POST['choice']);
|
||||
$result = $adminPollService->addSlot($poll_id, $newslot, null);
|
||||
$result = $adminPollService->addClassicSlot($poll_id, $newslot);
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
@ -366,7 +411,7 @@ if (isset($_POST['confirm_add_slot'])) {
|
||||
}
|
||||
|
||||
// Retrieve data
|
||||
$slots = $pollService->allSlotsByPollId($poll_id);
|
||||
$slots = $pollService->allSlotsByPoll($poll);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||
|
||||
@ -377,7 +422,7 @@ $smarty->assign('admin_poll_id', $admin_poll_id);
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
||||
$smarty->assign('expired', strtotime($poll->end_date) < time());
|
||||
$smarty->assign('deletion_date', $poll->end_date + PURGE_DELAY * 86400);
|
||||
$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400);
|
||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||
$smarty->assign('best_choices', $pollService->computeBestChoices($votes));
|
||||
|
@ -18,8 +18,6 @@
|
||||
*/
|
||||
namespace Framadate;
|
||||
|
||||
use Framadate\Editable;
|
||||
|
||||
class Form
|
||||
{
|
||||
|
||||
|
@ -61,7 +61,7 @@ class SlotRepository extends AbstractRepository {
|
||||
}
|
||||
|
||||
function listByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY title');
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute(array($poll_id));
|
||||
|
||||
return $prepared->fetchAll();
|
||||
|
@ -105,17 +105,21 @@ class AdminPollService {
|
||||
/**
|
||||
* Delete a slot from a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $slot object The slot informations (datetime + moment)
|
||||
* @param object $poll The ID of the poll
|
||||
* @param object $slot The slot informations (datetime + moment)
|
||||
* @return bool true if action succeeded
|
||||
*/
|
||||
public function deleteDateSlot($poll_id, $slot) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . json_encode($slot));
|
||||
public function deleteDateSlot($poll, $slot) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . json_encode($slot));
|
||||
|
||||
$datetime = $slot->title;
|
||||
$moment = $slot->moment;
|
||||
|
||||
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
||||
$slots = $this->pollService->allSlotsByPoll($poll);
|
||||
|
||||
if (count($slots) === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$index = 0;
|
||||
$indexToDelete = -1;
|
||||
@ -139,21 +143,25 @@ class AdminPollService {
|
||||
|
||||
// Remove votes
|
||||
$this->connect->beginTransaction();
|
||||
$this->voteRepository->deleteByIndex($poll_id, $indexToDelete);
|
||||
$this->voteRepository->deleteByIndex($poll->id, $indexToDelete);
|
||||
if (count($newMoments) > 0) {
|
||||
$this->slotRepository->update($poll_id, $datetime, implode(',', $newMoments));
|
||||
$this->slotRepository->update($poll->id, $datetime, implode(',', $newMoments));
|
||||
} else {
|
||||
$this->slotRepository->deleteByDateTime($poll_id, $datetime);
|
||||
$this->slotRepository->deleteByDateTime($poll->id, $datetime);
|
||||
}
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteClassicSlot($poll_id, $slot_title) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll_id . ', slot:' . $slot_title);
|
||||
public function deleteClassicSlot($poll, $slot_title) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . $slot_title);
|
||||
|
||||
$slots = $this->pollService->allSlotsByPollId($poll_id);
|
||||
$slots = $this->pollService->allSlotsByPoll($poll);
|
||||
|
||||
if (count($slots) === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$index = 0;
|
||||
$indexToDelete = -1;
|
||||
@ -168,15 +176,15 @@ class AdminPollService {
|
||||
|
||||
// Remove votes
|
||||
$this->connect->beginTransaction();
|
||||
$this->voteRepository->deleteByIndex($poll_id, $indexToDelete);
|
||||
$this->slotRepository->deleteByDateTime($poll_id, $slot_title);
|
||||
$this->voteRepository->deleteByIndex($poll->id, $indexToDelete);
|
||||
$this->slotRepository->deleteByDateTime($poll->id, $slot_title);
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new slot to the poll. And insert default values for user's votes.
|
||||
* Add a new slot to a date poll. And insert default values for user's votes.
|
||||
* <ul>
|
||||
* <li>Create a new slot if no one exists for the given date</li>
|
||||
* <li>Create a new moment if a slot already exists for the given date</li>
|
||||
@ -187,7 +195,7 @@ class AdminPollService {
|
||||
* @param $new_moment string The moment's name
|
||||
* @return bool true if added
|
||||
*/
|
||||
public function addSlot($poll_id, $datetime, $new_moment) {
|
||||
public function addDateSlot($poll_id, $datetime, $new_moment) {
|
||||
$slots = $this->slotRepository->listByPollId($poll_id);
|
||||
$result = $this->findInsertPosition($slots, $datetime, $new_moment);
|
||||
|
||||
@ -224,6 +232,44 @@ class AdminPollService {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new slot to a classic poll. And insert default values for user's votes.
|
||||
* <ul>
|
||||
* <li>Create a new slot if no one exists for the given title</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $title int The title
|
||||
* @return bool true if added
|
||||
*/
|
||||
public function addClassicSlot($poll_id, $title) {
|
||||
$slots = $this->slotRepository->listByPollId($poll_id);
|
||||
|
||||
// Check if slot already exists
|
||||
$titles = array_map(function ($slot) {
|
||||
return $slot->title;
|
||||
}, $slots);
|
||||
if (in_array($title, $titles)) {
|
||||
// The moment already exists
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Begin transaction
|
||||
$this->connect->beginTransaction();
|
||||
|
||||
// New slot
|
||||
$this->slotRepository->insert($poll_id, $title, null);
|
||||
// Set default votes
|
||||
$this->voteRepository->insertDefault($poll_id, count($slots));
|
||||
|
||||
// Commit transaction
|
||||
$this->connect->commit();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method find where to insert a datatime+moment into a list of slots.<br/>
|
||||
* Return the {insert:X}, where X is the index of the moment into the whole poll (ex: X=0 => Insert to the first column).
|
||||
|
@ -51,8 +51,7 @@ class InputService {
|
||||
}
|
||||
|
||||
public function filterTitle($title) {
|
||||
$filtered = filter_var($title, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => TITLE_REGEX]]);
|
||||
return $this->returnIfNotBlank($filtered);
|
||||
return $this->returnIfNotBlank($title);
|
||||
}
|
||||
|
||||
public function filterName($name) {
|
||||
@ -66,7 +65,7 @@ class InputService {
|
||||
|
||||
public function filterDescription($description) {
|
||||
$description = str_replace("\r\n", "\n", $description);
|
||||
return filter_var($description, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => DESCRIPTION_REGEX]]);
|
||||
return $description;
|
||||
}
|
||||
|
||||
public function filterBoolean($boolean) {
|
||||
@ -79,8 +78,7 @@ class InputService {
|
||||
|
||||
public function filterComment($comment) {
|
||||
$comment = str_replace("\r\n", "\n", $comment);
|
||||
$filtered = filter_var($comment, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => COMMENT_REGEX]]);
|
||||
return $this->returnIfNotBlank($filtered);
|
||||
return $this->returnIfNotBlank($comment);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,14 @@ class MailService {
|
||||
|
||||
private $smtp_allowed;
|
||||
|
||||
const DELAY_BEFORE_RESEND = 300;
|
||||
|
||||
const MAILSERVICE_KEY = 'mailservice';
|
||||
|
||||
private $logService;
|
||||
|
||||
function __construct($smtp_allowed) {
|
||||
$this->logService = new LogService();
|
||||
$this->smtp_allowed = $smtp_allowed;
|
||||
}
|
||||
|
||||
@ -13,10 +20,12 @@ class MailService {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
function send($to, $subject, $body, $param = '') {
|
||||
if ($this->smtp_allowed == true) {
|
||||
function send($to, $subject, $body, $msgKey = null) {
|
||||
if ($this->smtp_allowed == true && $this->canSendMsg($msgKey)) {
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
// Build headers
|
||||
|
||||
$subject = mb_encode_mimeheader(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'), 'UTF-8', 'B', "\n", 9);
|
||||
|
||||
$encoded_app = mb_encode_mimeheader(NOMAPPLICATION, 'UTF-8', 'B', "\n", 6);
|
||||
@ -39,11 +48,38 @@ class MailService {
|
||||
$headers .= "Auto-Submitted:auto-generated\n";
|
||||
$headers .= 'Return-Path: <>';
|
||||
|
||||
// Build body
|
||||
|
||||
$body = $body . '<br/><br/>' . __('Mail', 'Thanks for your trust.') . '<br/>' . NOMAPPLICATION . '<hr/>' . __('Mail', 'FOOTER');
|
||||
|
||||
mail($to, $subject, $body, $headers, $param);
|
||||
// Send mail
|
||||
|
||||
$this->sendMail($to, $subject, $body, $msgKey, $headers);
|
||||
}
|
||||
}
|
||||
|
||||
function canSendMsg($msgKey) {
|
||||
if ($msgKey == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION[self::MAILSERVICE_KEY])) {
|
||||
$_SESSION[self::MAILSERVICE_KEY] = [];
|
||||
}
|
||||
return !isset($_SESSION[self::MAILSERVICE_KEY][$msgKey]) || time() - $_SESSION[self::MAILSERVICE_KEY][$msgKey] > self::DELAY_BEFORE_RESEND;
|
||||
}
|
||||
|
||||
private function sendMail($to, $subject, $body, $msgKey, $headers) {
|
||||
mail($to, $subject, $body, $headers, '');
|
||||
|
||||
// Log
|
||||
|
||||
$this->logService->log('MAIL', 'Mail sent to: ' . $to . ', key: ' . $msgKey);
|
||||
|
||||
// Store the mail sending date
|
||||
|
||||
$_SESSION[self::MAILSERVICE_KEY][$msgKey] = time();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,8 +64,16 @@ class PollService {
|
||||
return $this->voteRepository->allUserVotesByPollId($poll_id);
|
||||
}
|
||||
|
||||
function allSlotsByPollId($poll_id) {
|
||||
return $this->slotRepository->listByPollId($poll_id);
|
||||
function allSlotsByPoll($poll) {
|
||||
$slots = $this->slotRepository->listByPollId($poll->id);
|
||||
if ($poll->format == 'D') {
|
||||
uasort($slots, function ($a, $b) {
|
||||
return $a->title > $b->title;
|
||||
});
|
||||
return $slots;
|
||||
} else {
|
||||
return $slots;
|
||||
}
|
||||
}
|
||||
|
||||
public function updateVote($poll_id, $vote_id, $name, $choices) {
|
||||
|
@ -24,9 +24,6 @@ const VERSION = '0.9';
|
||||
const POLL_REGEX = '/^[a-z0-9]+$/i';
|
||||
const CHOICE_REGEX = '/^[012]$/';
|
||||
const NAME_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9_ -]+$/i';
|
||||
const TITLE_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9\\/ &"\'(_)=~#{|`^@}$[\\]\\\\,;:!?.*-]+$/i';
|
||||
const DESCRIPTION_REGEX = "/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9\\/ &\"'(_)=~#{|`^@}$[\\]\\\\,;:!?.*\n-]*$/i";
|
||||
const COMMENT_REGEX = "/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9\\/ &\"'(_)=~#{|`^@}$[\\]\\\\,;:!?.*\n-]+$/i";
|
||||
const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/i';
|
||||
const BOOLEAN_TRUE_REGEX = '/^(on|true|1)$/i';
|
||||
const EDITABLE_CHOICE_REGEX = '/^[0-2]$/';
|
||||
|
@ -28,7 +28,7 @@ if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang'
|
||||
}
|
||||
|
||||
/* <html lang="$locale"> */
|
||||
$i18n->get('Something, just to load the dictionary');
|
||||
$i18n->get('', 'Something, just to load the dictionary');
|
||||
$locale = $i18n->getLoadedLang();
|
||||
|
||||
/* Date Format */
|
||||
|
23
app/tests/Framadate/FramaTestCase.php
Normal file
23
app/tests/Framadate/FramaTestCase.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace Framadate;
|
||||
|
||||
abstract class FramaTestCase extends \PHPUnit_Framework_TestCase {
|
||||
|
||||
protected function getTestResourcePath($resourcepath) {
|
||||
return __DIR__ . '/../resources/'.$resourcepath;
|
||||
}
|
||||
|
||||
protected function readTestResource($resourcepath) {
|
||||
return file_get_contents($this->getTestResourcePath($resourcepath));
|
||||
}
|
||||
|
||||
protected function invoke(&$object, $methodName) {
|
||||
$reflectionClass = new \ReflectionClass($object);
|
||||
$reflectionMethod = $reflectionClass->getMethod($methodName);
|
||||
$reflectionMethod->setAccessible(true);
|
||||
|
||||
$params = array_slice(func_get_args(), 2); // get all the parameters after $methodName
|
||||
return $reflectionMethod->invokeArgs($object, $params);
|
||||
}
|
||||
|
||||
}
|
39
app/tests/Framadate/Services/MailServiceUnitTest.php
Normal file
39
app/tests/Framadate/Services/MailServiceUnitTest.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\FramaTestCase;
|
||||
|
||||
class MailServiceUnitTest extends FramaTestCase {
|
||||
const MSG_KEY = '666';
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
function should_send_a_2nd_mail_after_a_good_interval() {
|
||||
// Given
|
||||
$mailService = new MailService(true);
|
||||
$_SESSION[MailService::MAILSERVICE_KEY] = [self::MSG_KEY => time() - 1000];
|
||||
|
||||
// When
|
||||
$canSendMsg = $mailService->canSendMsg(self::MSG_KEY);
|
||||
|
||||
// Then
|
||||
$this->assertEquals(true, $canSendMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
function should_not_send_2_mails_in_a_short_interval() {
|
||||
// Given
|
||||
$mailService = new MailService(true);
|
||||
$_SESSION[MailService::MAILSERVICE_KEY] = [self::MSG_KEY => time()];
|
||||
|
||||
// When
|
||||
$canSendMsg = $mailService->canSendMsg(self::MSG_KEY);
|
||||
|
||||
// Then
|
||||
$this->assertEquals(false, $canSendMsg);
|
||||
}
|
||||
|
||||
}
|
3
app/tests/bootstrap.php
Normal file
3
app/tests/bootstrap.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
$loader = require __DIR__ . '/../../vendor/autoload.php';
|
||||
$loader->addPsr4('Framadate\\', __DIR__.'/Framadate');
|
@ -14,6 +14,10 @@
|
||||
"o80/i18n": "dev-develop"
|
||||
},
|
||||
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.5"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Framadate\\": "app/classes/Framadate/"
|
||||
|
972
composer.lock
generated
972
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -41,13 +41,13 @@ if (file_exists('bandeaux_local.php')) {
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (($config['use_smtp']) ? empty($_SESSION['form']->admin_mail) : false)) {
|
||||
|
||||
Utils::print_header(__("Error!"));
|
||||
bandeau_titre(__("Error!"));
|
||||
Utils::print_header(__('Error', 'Error!'));
|
||||
bandeau_titre(__('Error', 'Error!'));
|
||||
|
||||
echo '
|
||||
<div class="alert alert-danger">
|
||||
<h3>' . __('You haven\'t filled the first section of the poll creation.') . ' !</h3>
|
||||
<p>' . __('Back to the homepage of') . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a></p>
|
||||
<h3>' . __('Error', 'You haven\'t filled the first section of the poll creation.') . ' !</h3>
|
||||
<p>' . __('Generic', 'Back to the homepage of') . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a></p>
|
||||
</div>' . "\n";
|
||||
|
||||
bandeau_pied();
|
||||
@ -149,7 +149,7 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
|
||||
|
||||
// Summary
|
||||
$summary = '<ol>';
|
||||
foreach ($_SESSION['form']->getChoices() as $choice) {
|
||||
foreach ($_SESSION['form']->getChoices() as $i=>$choice) {
|
||||
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/', $choice->getName(), $md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/', $choice->getName(), $md_img); // Markdown ![alt](src)
|
||||
@ -198,7 +198,7 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="' . __('Date', 'dd/mm/yyyy') . '" aria-describedby="dateformat" name="enddate" value="' . $end_date_str . '" size="10" maxlength="10" placeholder="' . __("dd/mm/yyyy") . '" />
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="' . __('Date', 'dd/mm/yyyy') . '" aria-describedby="dateformat" name="enddate" value="' . $end_date_str . '" size="10" maxlength="10" placeholder="' . __('Date', 'dd/mm/yyyy') . '" />
|
||||
</div>
|
||||
</div>
|
||||
<span id="dateformat" class="sr-only">' . __('Date', 'dd/mm/yyyy') . '</span>
|
||||
|
@ -194,7 +194,7 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group date">
|
||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span>
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="'. __('Date', 'dd/mm/yyyy') .'" aria-describedby="dateformat" name="enddate" value="'.$end_date_str.'" size="10" maxlength="10" placeholder="'. __('dd/mm/yyyy') .'" />
|
||||
<input type="text" class="form-control" id="enddate" data-date-format="'. __('Date', 'dd/mm/yyyy') .'" aria-describedby="dateformat" name="enddate" value="'.$end_date_str.'" size="10" maxlength="10" placeholder="'. __('Date', 'dd/mm/yyyy') .'" />
|
||||
</div>
|
||||
</div>
|
||||
<span id="dateformat" class="sr-only">('. __('Date', 'dd/mm/yyyy') .')</span>
|
||||
@ -221,17 +221,15 @@ if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) ||
|
||||
} else {
|
||||
|
||||
// Prefill form->choices
|
||||
if (count($_SESSION['form']->getChoices()) == 0) {
|
||||
$c = new Choice('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$_SESSION['form']->addChoice($c);
|
||||
$c = new Choice('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$_SESSION['form']->addChoice($c);
|
||||
foreach ($_SESSION['form']->getChoices() as $c) {
|
||||
$count = 3 - count($c->getSlots());
|
||||
for($i=0; $i< $count; $i++) {
|
||||
$c->addSlot('');
|
||||
}
|
||||
}
|
||||
|
||||
$count = 3 - count($_SESSION['form']->getChoices());
|
||||
for($i=0; $i< $count; $i++) {
|
||||
$c = new Choice('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
|
@ -90,7 +90,7 @@ if ($goToStep2) {
|
||||
$error_on_name = true;
|
||||
}
|
||||
|
||||
if ($description !== $_POST['description']) {
|
||||
if ($description === false) {
|
||||
$error_on_description = true;
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,6 @@
|
||||
*/
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Message;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
@ -54,7 +51,7 @@ if (!$poll) {
|
||||
}
|
||||
|
||||
|
||||
$slots = $pollService->allSlotsByPollId($poll_id);
|
||||
$slots = $pollService->allSlotsByPoll($poll);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
|
||||
// CSV header
|
||||
|
@ -43,7 +43,7 @@ if (!empty($_POST['mail'])) {
|
||||
$smarty->assign('polls', $polls);
|
||||
$body = $smarty->fetch('mail/find_polls.tpl');
|
||||
|
||||
$mailService->send($mail, __('Homepage', 'Where are my polls'), $body);
|
||||
$mailService->send($mail, __('Homepage', 'Where are my polls'), $body, 'SEND_POLLS');
|
||||
$message = new Message('success', __('FindPolls', 'Polls sent'));
|
||||
} else {
|
||||
$message = new Message('warning', __('Error', 'No polls found'));
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 9.5 KiB |
@ -17,9 +17,7 @@
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
|
@ -28,11 +28,21 @@
|
||||
});
|
||||
if (nb_filled_choices >= 1) {
|
||||
$('button[name="fin_sondage_autre"]').removeClass('disabled');
|
||||
return true;
|
||||
} else {
|
||||
$('button[name="fin_sondage_autre"]').addClass('disabled');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Handle form submission
|
||||
$(document.formulaire).on('submit', function (e) {
|
||||
if (!submitChoicesAvalaible()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// Button "Add a choice"
|
||||
|
||||
$('#add-a-choice').on('click', function () {
|
||||
|
@ -42,11 +42,21 @@ $(document).ready(function () {
|
||||
|
||||
if (nb_filled_days >= 1 && nb_filled_hours >= 1) {
|
||||
$('button[name="choixheures"]').removeClass('disabled');
|
||||
return true;
|
||||
} else {
|
||||
$('button[name="choixheures"]').addClass('disabled');
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Handle form submission
|
||||
$(document.formulaire).on('submit', function (e) {
|
||||
if (!submitDaysAvalaible()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// Button "Remove all hours"
|
||||
|
||||
$(document).on('click', '#resethours', function () {
|
||||
|
@ -47,7 +47,7 @@ $(document).ready(function () {
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on('click', '.input-group.date .input-group-addon', function () {
|
||||
$(document).on('click', '.input-group.date .input-group-addon, .input-group.date input', function () {
|
||||
// Re-init datepicker config before displaying
|
||||
init_datepicker();
|
||||
$(this).parent().datepicker('show');
|
||||
|
@ -189,7 +189,6 @@
|
||||
"Remove the comments": "Entfernen Sie die Kommentare",
|
||||
"Comment deleted": "Kommentar gelöscht",
|
||||
"All comments deleted": "Alle Kommentare gelöscht",
|
||||
"The poll has been deleted": "Die Umfrage wurde gelöscht",
|
||||
"Keep votes": "Halten Stimmen",
|
||||
"Keep comments": "Halten Sie Kommentare",
|
||||
"Keep this poll": "Halten Sie diese Umfrage"
|
||||
@ -200,11 +199,11 @@
|
||||
"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.",
|
||||
"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": {
|
||||
@ -289,9 +288,12 @@
|
||||
},
|
||||
"Mail": {
|
||||
"Poll's participation": "Beteiligung an der Umfrage",
|
||||
"Notification of poll": "Mitteilung bezüglich der Umfrage",
|
||||
"filled a vote.\nYou can find your poll at the link": "füllte eine Stimme.<br/>Sie können Ihre Umfrage unter dem Link zu finden",
|
||||
"updated a vote.\nYou can find your poll at the link": "eine Abstimmung regelmäßig aktualisiert.<br/>Sie können Ihre Umfrage unter dem Link zu finden",
|
||||
"wrote a comment.\nYou can find your poll at the link": "hat einen Kommentar.<br/>Sie können Ihre Umfrage unter dem Link zu finden",
|
||||
"Someone just change your poll available at the following link %s.": "Jemand ändern Sie einfach Ihre Umfrage finden Sie unter dem folgenden Link <a href=\"%1$s\">%1$s</a>.",
|
||||
"Someone just delete your poll %s.": "Jemand hat gerade Ihre Umfrage löschen \"%s\".",
|
||||
"Thanks for your trust.": "Danke für Ihr Vertrauen.",
|
||||
"FOOTER": "",
|
||||
"[ADMINISTRATOR] New settings for your poll": "[ADMINISTRATOR] Neue Einstellungen für Ihre Umfrage ",
|
||||
@ -326,6 +328,7 @@
|
||||
"Update vote failed": "Update vote failed",
|
||||
"Adding vote failed": "Adding vote failed",
|
||||
"Comment failed": "Kommentar gescheitert",
|
||||
"You can't create a poll with hidden results with the following edition option:": "Sie können nicht eine Umfrage erstellen mit versteckten Ergebnisse mit der folgenden Ausgabe-Option:"
|
||||
"You can't create a poll with hidden results with the following edition option:": "Sie können nicht eine Umfrage erstellen mit versteckten Ergebnisse mit der folgenden Ausgabe-Option:",
|
||||
"Failed to delete column": "Fehler beim Spalte löschen"
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@
|
||||
"All comments deleted": "All comments deleted",
|
||||
"Keep the comments": "Keep the comments",
|
||||
"Remove the comments": "Remove the comments",
|
||||
"The poll has been deleted": "The poll has been deleted",
|
||||
"Keep votes": "Keep votes",
|
||||
"Keep comments": "Keep comments",
|
||||
"Keep this poll": "Keep this poll"
|
||||
@ -200,11 +199,11 @@
|
||||
"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.",
|
||||
"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": {
|
||||
@ -289,9 +288,12 @@
|
||||
},
|
||||
"Mail" : {
|
||||
"Poll's participation": "Poll's participation",
|
||||
"Notification of poll": "Notification of poll",
|
||||
"filled a vote.\nYou can find your poll at the link": "filled a vote.<br/>You can find your poll at the link",
|
||||
"updated a vote.\nYou can find your poll at the link": "updated a vote.<br/>You can find your poll at the link",
|
||||
"wrote a comment.\nYou can find your poll at the link": "wrote a comment.<br/>You can find your poll at the link",
|
||||
"Someone just change your poll available at the following link %s.": "Someone just change your poll available at the following link <a href=\"%1$s\">%1$s</a>.",
|
||||
"Someone just delete your poll %s.": "Someone just delete your poll \"%s\".",
|
||||
"Thanks for your trust.": "Thanks for your trust.",
|
||||
"FOOTER": "",
|
||||
"[ADMINISTRATOR] New settings for your poll": "[ADMINISTRATOR] New settings for your poll",
|
||||
@ -326,6 +328,7 @@
|
||||
"Update vote failed": "Update vote failed",
|
||||
"Adding vote failed": "Adding vote failed",
|
||||
"Comment failed": "Comment 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: "
|
||||
"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: ",
|
||||
"Failed to delete column": "Failed to delete column"
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@
|
||||
"Remove the comments": "ES_Supprimer les commentaires",
|
||||
"Comment deleted": "ES_Commentaire supprimé",
|
||||
"All comments deleted": "ES_Tous les commentaires ont été supprimés",
|
||||
"The poll has been deleted": "ES_Le sondage a été supprimé",
|
||||
"Keep votes": "ES_Garder les votes",
|
||||
"Keep comments": "ES_Garder les commentaires",
|
||||
"Keep this poll": "Dejar este encuesta!"
|
||||
@ -200,11 +199,11 @@
|
||||
"Required fields cannot be left blank.": "Gracias por completar los campos con una *.",
|
||||
"Poll title": "ES_Titre du sondage",
|
||||
"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.",
|
||||
"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": {
|
||||
@ -244,7 +243,7 @@
|
||||
"Confirm the creation of your poll": "ES_Confirmez la création de votre sondage",
|
||||
"List of your choices": "ES_Liste de vos choix",
|
||||
"Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll.": "ES_Une fois que vous aurez confirmé la création du sondage, vous serez redirigé automatiquement vers la page d'administration de votre sondage.",
|
||||
"Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.": "ES_En même temps, vous recevrez deux courriels : l'un contenant le lien vers votre sondage pour le faire suivre aux futurs sondés, l'autre contenant le lien vers la page d'administraion du sondage.",
|
||||
"Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.": "ES_En même temps, vous recevrez deux courriels : l'un contenant le lien vers votre sondage pour le faire suivre aux futurs sondés, l'autre contenant le lien vers la page d'administration du sondage.",
|
||||
"Create the poll": "Crear la encuesta",
|
||||
"Your poll will automatically be archived": "ES_Votre sondage sera automatiquement archivé",
|
||||
"after the last date of your poll.": "ES_après la date la plus tardive.",
|
||||
@ -288,10 +287,13 @@
|
||||
"Polls sent": "ES_Sondages envoyés"
|
||||
},
|
||||
"Mail": {
|
||||
"Poll's participation": "ES_Participation au sondage",
|
||||
"Poll's participation": "Participación Encuesta",
|
||||
"Notification of poll": "Notificación de la encuesta",
|
||||
"filled a vote.\nYou can find your poll at the link": "ES_vient de voter.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"updated a vote.\nYou can find your poll at the link": "ES_vient de mettre à jour un vote.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"wrote a comment.\nYou can find your poll at the link": "ES_vient de rédiger un commentaire.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"Someone just change your poll available at the following link %s.": "Alguien acaba de cambiar su encuesta disponible en el siguiente enlace <a href=\"%1$s\">%1$s</a>.",
|
||||
"Someone just delete your poll %s.": "Alguien acaba de borrar tu encuesta \"%s\".",
|
||||
"Thanks for your trust.": "ES_Merci de votre confiance.",
|
||||
"FOOTER": "",
|
||||
"[ADMINISTRATOR] New settings for your poll": "ES_[ADMINISTRATEUR] Changement de configuration du sondage",
|
||||
@ -306,8 +308,8 @@
|
||||
"Error": {
|
||||
"Error!": "Error!",
|
||||
"Enter a title": "Introducza un título",
|
||||
"Something is going wrong...": "ES_Quelque chose ne va pas...",
|
||||
"Something is wrong with the format": "Something is wrong with the format",
|
||||
"Something is going wrong...": "Algo va mal...",
|
||||
"Something is wrong with the format": "Algo está mal con el formato",
|
||||
"Enter an email address": "Introduzca una dirección electrónica",
|
||||
"The address is not correct! You should enter a valid email address (like r.stallman@outlock.com) in order to receive the link to your poll.": "ES_L'adresse saisie n'est pas correcte ! Il faut une adresse électronique valide (par exemple r.stallman@outlock.com) pour recevoir le lien vers le sondage.",
|
||||
"No polls found": "ES_Aucun sondage n'a été trouvé",
|
||||
@ -322,10 +324,11 @@
|
||||
"Enter a name and a comment!": "Introduzca su nombre y un comentario!",
|
||||
"Failed to insert the comment!": "ES_Échec à l'insertion du commentaire !",
|
||||
"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",
|
||||
"Failed to save poll": "ES_Echec de la sauvegarde du sondage",
|
||||
"Update vote failed": "ES_Mise à jour du vote échoué",
|
||||
"Adding vote failed": "ES_Ajout d'un vote échoué",
|
||||
"Comment failed": "ES_Commentaire é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 : "
|
||||
"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 : ",
|
||||
"Failed to delete column": "Error al eliminar la columna"
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@
|
||||
"Remove the comments": "Supprimer les commentaires",
|
||||
"Comment deleted": "Commentaire supprimé",
|
||||
"All comments deleted": "Tous les commentaires ont été supprimés",
|
||||
"The poll has been deleted": "Le sondage a été supprimé",
|
||||
"Keep votes": "Garder les votes",
|
||||
"Keep comments": "Garder les commentaires",
|
||||
"Keep this poll": "Garder ce sondage"
|
||||
@ -200,11 +199,11 @@
|
||||
"Required fields cannot be left blank.": "Merci de remplir les champs obligatoires, marqués d'une *.",
|
||||
"Poll title": "Titre du sondage",
|
||||
"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.",
|
||||
"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": {
|
||||
@ -244,7 +243,7 @@
|
||||
"Confirm the creation of your poll": "Confirmez la création de votre sondage",
|
||||
"List of your choices": "Liste de vos choix",
|
||||
"Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll.": "Une fois que vous aurez confirmé la création du sondage, vous serez redirigé automatiquement vers la page d'administration de votre sondage.",
|
||||
"Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.": "En même temps, vous recevrez deux courriels : l'un contenant le lien vers votre sondage pour le faire suivre aux futurs sondés, l'autre contenant le lien vers la page d'administraion du sondage.",
|
||||
"Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.": "En même temps, vous recevrez deux courriels : l'un contenant le lien vers votre sondage pour le faire suivre aux futurs sondés, l'autre contenant le lien vers la page d'administration du sondage.",
|
||||
"Create the poll": "Créer le sondage",
|
||||
"Your poll will automatically be archived": "Votre sondage sera automatiquement archivé",
|
||||
"after the last date of your poll.": "après la date la plus tardive.",
|
||||
@ -289,9 +288,12 @@
|
||||
},
|
||||
"Mail": {
|
||||
"Poll's participation": "Participation au sondage",
|
||||
"Notification of poll": "Notification d'un sondage",
|
||||
"filled a vote.\nYou can find your poll at the link": "vient de voter.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"updated a vote.\nYou can find your poll at the link": "vient de mettre à jour un vote.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"wrote a comment.\nYou can find your poll at the link": "vient de rédiger un commentaire.<br/>Vous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"Someone just change your poll available at the following link %s.": "Quelqu'un vient de modifier votre sondage accessible au lien suivant <a href=\"%1$s\">%1$s</a>.",
|
||||
"Someone just delete your poll %s.": "Quelqu'un vient de supprimer votre sondage \"%s\".",
|
||||
"Thanks for your trust.": "Merci de votre confiance.",
|
||||
"FOOTER": "« La route est longue, mais la voie est libre… »<br/>Framasoft ne vit que par vos dons (déductibles des impôts).<br/>Merci d'avance pour votre soutien http://soutenir.framasoft.org.",
|
||||
"[ADMINISTRATOR] New settings for your poll": "[ADMINISTRATEUR] Changement de configuration du sondage",
|
||||
@ -322,10 +324,11 @@
|
||||
"Enter a name and a comment!": "Merci de remplir les deux champs !",
|
||||
"Failed to insert the comment!": "Échec à l'insertion du commentaire !",
|
||||
"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",
|
||||
"Failed to save poll": "Echec de la sauvegarde du sondage",
|
||||
"Update vote failed": "Mise à jour du vote échoué",
|
||||
"Adding vote failed": "Ajout d'un vote échoué",
|
||||
"Comment failed": "Commentaire é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 : "
|
||||
"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 : ",
|
||||
"Failed to delete column": "Échec de la suppression de colonne"
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,6 @@
|
||||
"Remove the comments": "Eliminare i commenti",
|
||||
"Comment deleted": "Commento rimosso",
|
||||
"All comments deleted": "Tutti i commenti sono stati cancellati",
|
||||
"The poll has been deleted": "Il sondaggio è stato eliminato",
|
||||
"Keep votes": "Tenere voti",
|
||||
"Keep comments": "Tenere commenti",
|
||||
"Keep this poll": "Mantengo questo sondaggio !"
|
||||
@ -200,11 +199,11 @@
|
||||
"Required fields cannot be left blank.": "Riempire i campi obbligatori, segnati con *.",
|
||||
"Poll title": "Titolo del sondaggio",
|
||||
"Votes cannot be modified.": "No voto non può essere modificato",
|
||||
"All voters can modify any vote.": "Tutti i sondaggi possono cambiare tutti i voti",
|
||||
"Voters can modify their vote themselves.": "I partecipanti possono modificare il loro voto in autonomia.",
|
||||
"To receive an email for each new vote.": "Per ricevere un'email per ogni voto nuovo",
|
||||
"To receive an email for each new comment.": "Ricevi una e-mail ogni commento.",
|
||||
"Only the poll maker can see the poll's results.": "Solo il creatore sondaggio possono vedere i risultati.",
|
||||
"All voters can modify any vote": "Tutti i sondaggi possono cambiare tutti i voti",
|
||||
"Voters can modify their vote themselves": "I partecipanti possono modificare il loro voto in autonomia",
|
||||
"To receive an email for each new vote": "Per ricevere un'email per ogni voto nuovo",
|
||||
"To receive an email for each new comment": "Ricevi una e-mail ogni commento",
|
||||
"Only the poll maker can see the poll's results": "Solo il creatore sondaggio possono vedere i risultati",
|
||||
"Go to step 2": "Andare al punto 2"
|
||||
},
|
||||
"Step 2": {
|
||||
@ -245,7 +244,7 @@
|
||||
"List of your choices": "Liste delle vostre scelte",
|
||||
"Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll.": "Un volta che avrete confermato la creazione del sondaggio, sarete rediretti automaticamente sulla pagina di amministrazione del vostro sondaggio.",
|
||||
"Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.": "Nello stesso momento, riceverete 2 email : una con il Link verso il vostro sondaggio da inoltrare ai partecipanti, l'altra con il Link verso la pagina di amministrazione del sondaggio.",
|
||||
"Create the poll": "Creare le sondaggio",
|
||||
"Create the poll": "Creare il sondaggio",
|
||||
"Your poll will automatically be archived": "La vostra indagine verrà archiviata automaticamente",
|
||||
"after the last date of your poll.": "dopo l'ultima data.",
|
||||
"You can set a closer archiving date for it.": "Si può decidere su una data più vicina di archiviazione.",
|
||||
@ -289,9 +288,12 @@
|
||||
},
|
||||
"Mail": {
|
||||
"Poll's participation": "Partecipazione al sondaggio",
|
||||
"Notification of poll": "Notifica di sondaggio",
|
||||
"filled a vote.\nYou can find your poll at the link": "IT_vient de voter.\nVous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"updated a vote.\nYou can find your poll at the link": "IT_vient de mettre à jour un vote.\nVous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"wrote a comment.\nYou can find your poll at the link": "IT_vient de rédiger un commentaire.\nVous pouvez retrouver votre sondage avec le lien suivant",
|
||||
"Someone just change your poll available at the following link %s.": "Qualcuno basta cambiare il vostro sondaggio disponibile al seguente link <a href=\"%1$s\">%1$s</a>.",
|
||||
"Someone just delete your poll %s.": "Qualcuno ha appena cancellare il tuo sondaggio \"%s\".",
|
||||
"Thanks for your trust.": "Grazie per la vostra fiducia.",
|
||||
"FOOTER": "IT_« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org.",
|
||||
"[ADMINISTRATOR] New settings for your poll": "[AMMINISTRATORE] Modifica di configurazione del sondaggio",
|
||||
@ -322,10 +324,11 @@
|
||||
"Enter a name and a comment!": "Inserire un nome e un commento!",
|
||||
"Failed to insert the comment!": "Errore nell'inserimento del commento !",
|
||||
"Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "IT_Framadate n'est pas installé correctement, lisez le fichier INSTALL pour configurer la base de données avant de continuer.",
|
||||
"Failed to save poll": "IT_Echèc de la sauvegarde du sondage",
|
||||
"Failed to save poll": "IT_Echec de la sauvegarde du sondage",
|
||||
"Update vote failed": "IT_Mise à jour du vote échoué",
|
||||
"Adding vote failed": "IT_Ajout d'un vote échoué",
|
||||
"Comment failed": "IT_Commentaire échoué",
|
||||
"You can't create a poll with hidden results with the following edition option:": "IT_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : "
|
||||
"You can't create a poll with hidden results with the following edition option:": "IT_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : ",
|
||||
"Failed to delete column": "Impossibile eliminare colonna"
|
||||
}
|
||||
}
|
1
phpunit.bat
Normal file
1
phpunit.bat
Normal file
@ -0,0 +1 @@
|
||||
vendor\bin\phpunit.bat --bootstrap app\tests\bootstrap.php app/tests
|
1
phpunit.sh
Normal file
1
phpunit.sh
Normal file
@ -0,0 +1 @@
|
||||
vendor\bin\phpunit --bootstrap app\tests\bootstrap.php app/tests
|
13
studs.php
13
studs.php
@ -64,7 +64,7 @@ function sendUpdateNotification($poll, $mailService, $name, $type) {
|
||||
$_SESSION['mail_sent'] = [];
|
||||
}
|
||||
|
||||
if ($poll->receiveNewVotes && (!isset($_SESSION['mail_sent'][$poll->id]) || $_SESSION['mail_sent'][$poll->id] !== true)) {
|
||||
if ($poll->receiveNewVotes) {
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __('Mail', 'Poll\'s participation') . ' : ' . $poll->title;
|
||||
|
||||
@ -82,9 +82,8 @@ function sendUpdateNotification($poll, $mailService, $name, $type) {
|
||||
}
|
||||
$message .= Utils::getUrlSondage($poll->admin_id, true) . "\n\n";
|
||||
|
||||
$mailService->send($poll->admin_mail, $subject, $message);
|
||||
|
||||
$_SESSION['mail_sent'][$poll->id] = true;
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +151,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
$message = new Message('danger', __('Error', 'The name is invalid.'));
|
||||
}
|
||||
if (count($choices) != count($_POST['choices'])) {
|
||||
$message = new Message('danger', __('There is a problem with your choices'));
|
||||
$message = new Message('danger', __('Error', 'There is a problem with your choices'));
|
||||
}
|
||||
|
||||
if ($message == null) {
|
||||
@ -198,7 +197,7 @@ if (isset($_POST['add_comment'])) {
|
||||
}
|
||||
|
||||
// Retrieve data
|
||||
$slots = $pollService->allSlotsByPollId($poll_id);
|
||||
$slots = $pollService->allSlotsByPoll($poll);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||
|
||||
@ -207,7 +206,7 @@ $smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
||||
$smarty->assign('expired', strtotime($poll->end_date) < time());
|
||||
$smarty->assign('deletion_date', $poll->end_date + PURGE_DELAY * 86400);
|
||||
$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400);
|
||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||
$smarty->assign('best_choices', $pollService->computeBestChoices($votes));
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
{block 'admin_main'}
|
||||
{if $message}
|
||||
<div class="alert alert-dismissible alert-info" role="alert">{$message|html}<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>
|
||||
<div class="alert alert-dismissible alert-info" role="alert">{$message|html}<button type="button" class="close" data-dismiss="alert" aria-label="{__('Generic', 'Close')}"><span aria-hidden="true">×</span></button></div>
|
||||
{/if}
|
||||
<form action="" method="POST">
|
||||
<input type="hidden" name="csrf" value="{$crsf}"/>
|
||||
<div class="text-center">
|
||||
<button type="submit" name="action" value="purge" class="btn btn-warning">{__('Admin', 'Purge the polls')} <span class="glyphicon glyphicon-trash text-danger"></span></button>
|
||||
<button type="submit" name="action" value="purge" class="btn btn-danger">{__('Admin', 'Purge the polls')} <span class="glyphicon glyphicon-trash"></span></button>
|
||||
</div>
|
||||
</form>
|
||||
{/block}
|
||||
|
@ -102,11 +102,11 @@
|
||||
</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.')}
|
||||
{__('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.')}
|
||||
{__('Step 1', 'Voters can modify their vote themselves')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -120,7 +120,7 @@
|
||||
<label>
|
||||
<input type="checkbox" name="receiveNewVotes" {if $poll_receiveNewVotes}checked{/if}
|
||||
id="receiveNewVotes">
|
||||
{__('Step 1', 'To receive an email for each new vote.')}
|
||||
{__('Step 1', 'To receive an email for each new vote')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -131,7 +131,7 @@
|
||||
<label>
|
||||
<input type="checkbox" name="receiveNewComments" {if $poll_receiveNewComments}checked{/if}
|
||||
id="receiveNewComments">
|
||||
{__('Step 1', 'To receive an email for each new comment.')}
|
||||
{__('Step 1', 'To receive an email for each new comment')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -142,12 +142,12 @@
|
||||
<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.")}
|
||||
{__('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.')}"
|
||||
{__('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>
|
||||
|
@ -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="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">
|
||||
@ -15,10 +15,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-md-offset-3 text-center">
|
||||
<button type="submit" class="btn btn-warning btn-lg">
|
||||
<span class="glyphicon glyphicon-search"></span>
|
||||
{__('FindPolls', 'Send me my polls')}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success">{__('FindPolls', 'Send me my polls')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -29,8 +29,6 @@
|
||||
<div class="col-md-6 col-md-offset-3 text-center">
|
||||
<p class="home-choice">
|
||||
<a href="{$SERVER_URL}find_polls.php" class="opacity" role="button">
|
||||
<img alt="" class="img-responsive center-block" src="{'images/question.png'|resource}"/>
|
||||
<br/>
|
||||
<span class="btn btn-warning btn-lg">
|
||||
<span class="glyphicon glyphicon-search"></span>
|
||||
{__('Homepage', 'Where are my polls')}
|
||||
|
@ -20,7 +20,7 @@
|
||||
<script type="text/javascript" src="{"js/locales/bootstrap-datepicker.$locale.js"|resource}"></script>
|
||||
<script type="text/javascript" src="{'js/core.js'|resource}"></script>
|
||||
|
||||
{if !empty($nav_js)}
|
||||
{if $use_nav_js}
|
||||
<script src="{'nav/nav.js'|resource}" id="nav_js" type="text/javascript" charset="utf-8"></script><!-- /Framanav -->
|
||||
{/if}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
<button type="submit" name="delete_comment" value="{$comment->id|html}" class="btn btn-link" title="{__('Comments', 'Remove the comment')}"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span></button>
|
||||
{/if}
|
||||
<b>{$comment->name|html}</b>
|
||||
<span class="comment">{nl2br($comment->comment|html)}</span>
|
||||
<span class="comment">{$comment->comment|escape|nl2br}</span>
|
||||
</div>
|
||||
{/foreach}
|
||||
{/if}
|
||||
@ -22,8 +22,8 @@
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<fieldset id="add-comment"><legend>{__('Comments', 'Add a comment to the poll')}</legend>
|
||||
<div class="form-group">
|
||||
<label for="name" class="control-label">{__('Generic', 'Your name')}</label>
|
||||
<input type="text" name="name" id="name" class="form-control" />
|
||||
<label for="comment_name" class="control-label">{__('Generic', 'Your name')}</label>
|
||||
<input type="text" name="name" id="comment_name" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="comment" class="control-label">{__('Comments', 'Your comment')}</label>
|
||||
|
@ -38,85 +38,86 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $votes as $vote}
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId === $vote->uniqId}
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<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>
|
||||
{if $editingVoteId === $vote->uniqId} {* Edited line *}
|
||||
|
||||
<tr class="hidden-print">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<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>
|
||||
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
|
||||
<td class="bg-info" headers="C{$id}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('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')|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')|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" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
</tr>
|
||||
{elseif !$hidden} {* Voted line *}
|
||||
<tr>
|
||||
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
|
||||
<td class="bg-info" headers="C{$id}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('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')|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')|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" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{elseif !$hidden}
|
||||
{* Voted line *}
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
|
||||
{foreach $vote->choices as $id=>$choice}
|
||||
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="C{$id}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="C{$id}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td class="bg-danger" headers="C{$id}"><span class="sr-only">{__('Generic', 'No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<td>
|
||||
<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}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
<a href="{poll_url id=$admin_poll_id admin=true action='delete_vote' action_value=$vote->id}"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="C{$id}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="C{$id}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td></td>
|
||||
<td class="bg-danger" headers="C{$id}"><span class="sr-only">{__('Generic', 'No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<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}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
<a href="{poll_url id=$admin_poll_id admin=true action='delete_vote' action_value=$vote->id}"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId === 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<tr id="vote-form" class="hidden-print">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
|
@ -86,86 +86,89 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $votes as $vote}
|
||||
<tr>
|
||||
{* Edited line *}
|
||||
{* Edited line *}
|
||||
|
||||
{if $editingVoteId === $vote->uniqId && !$expired}
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<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>
|
||||
{if $editingVoteId === $vote->uniqId && !$expired}
|
||||
<tr class="hidden-print">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<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>
|
||||
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
|
||||
<td class="bg-info" headers="M{$headersM[$k]} D{$headersD[$k]} H{$headersH[$k]}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$k}" name="choices[{$k}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$k}" title="{__('Poll results', 'Vote yes for')|html} {$slots_raw[$k]}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$k}" name="choices[{$k}]" value="1" {if $choice==1}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$k}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slots_raw[$k]}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$k}" name="choices[{$k}]" value="0" {if $choice==0}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$k}" title="{__('Poll results', 'Vote no for')|html} {$slots_raw[$k]}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Generic', 'No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
</tr>
|
||||
{elseif !$hidden}
|
||||
<tr>
|
||||
|
||||
<td class="bg-info" headers="M{$headersM[$k]} D{$headersD[$k]} H{$headersH[$k]}">
|
||||
<ul class="list-unstyled choice">
|
||||
<li class="yes">
|
||||
<input type="radio" id="y-choice-{$k}" name="choices[{$k}]" value="2" {if $choice==2}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="y-choice-{$k}" title="{__('Poll results', 'Vote yes for')|html} {$slots_raw[$k]}">
|
||||
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="ifneedbe">
|
||||
<input type="radio" id="i-choice-{$k}" name="choices[{$k}]" value="1" {if $choice==1}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="i-choice-{$k}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slots_raw[$k]}">
|
||||
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span>
|
||||
</label>
|
||||
</li>
|
||||
<li class="no">
|
||||
<input type="radio" id="n-choice-{$k}" name="choices[{$k}]" value="0" {if $choice==0}checked {/if}/>
|
||||
<label class="btn btn-default btn-xs" for="n-choice-{$k}" title="{__('Poll results', 'Vote no for')|html} {$slots_raw[$k]}">
|
||||
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Generic', 'No')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
{/foreach}
|
||||
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
|
||||
{elseif !$hidden}
|
||||
{* Voted line *}
|
||||
|
||||
{* Voted line *}
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
|
||||
<th class="bg-info">{$vote->name|html}</th>
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
|
||||
{foreach $vote->choices as $k=>$choice}
|
||||
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td class="bg-danger" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="sr-only">{__('Generic', 'No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<td>
|
||||
<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}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
<a href="{poll_url id=$admin_poll_id admin=true action='delete_vote' action_value=$vote->id}"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
{if $choice==2}
|
||||
<td class="bg-success text-success" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span></td>
|
||||
{elseif $choice==1}
|
||||
<td class="bg-warning text-warning" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}">(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span></td>
|
||||
{else}
|
||||
<td></td>
|
||||
<td class="bg-danger" headers="M{$headersM[$k]} D{$headersD[$k]} H{$k}"><span class="sr-only">{__('Generic', 'No')}</span></td>
|
||||
{/if}
|
||||
|
||||
{/foreach}
|
||||
|
||||
{if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
|
||||
<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}">
|
||||
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
|
||||
</a>
|
||||
{if $admin}
|
||||
<a href="{poll_url id=$admin_poll_id admin=true action='delete_vote' action_value=$vote->id}"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
|
||||
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
{else}
|
||||
<td></td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
|
||||
{* Line to add a new vote *}
|
||||
|
||||
{if $active && $editingVoteId === 0 && !$expired}
|
||||
<tr id="vote-form">
|
||||
<tr id="vote-form" class="hidden-print">
|
||||
<td class="bg-info" style="padding:5px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
|
||||
|
@ -1,8 +1,8 @@
|
||||
{extends file='page.tpl'}
|
||||
|
||||
{block name=main}
|
||||
<div class="alert alert-success text-center">
|
||||
<h2>{__('adminstuds', 'The poll has been deleted')}</h2>
|
||||
<div class="alert alert-{$message->type} text-center">
|
||||
<h2>{$message->message}</h2>
|
||||
<p>{__('Generic', 'Back to the homepage of')} <a href="{$SERVER_URL|html}">{$APPLICATION_NAME|html}</a></p>
|
||||
</div>
|
||||
{/block}
|
@ -9,10 +9,10 @@
|
||||
|
||||
<div id="message-container">
|
||||
{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="Close"><span aria-hidden="true">×</span></button></div>
|
||||
<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>
|
||||
{/if}
|
||||
</div>
|
||||
<div id="nameErrorMessage" class="hidden alert alert-dismissible alert-danger" role="alert">{__('Error', 'The name is invalid.')}<button type="button" class="close" data-dismiss="alert" aria-label="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>
|
||||
|
||||
|
||||
{* Global informations about the current poll *}
|
||||
|
Loading…
Reference in New Issue
Block a user