Merge branch 'develop' into 'master'

Version 1.1.0-beta.4

See merge request framasoft/framadate!287
This commit is contained in:
Thomas Citharel 2018-04-10 12:49:52 +02:00
commit 45b646b178
18 changed files with 128 additions and 42 deletions

View File

@ -29,6 +29,7 @@ use Framadate\Services\LogService;
use Framadate\Services\MailService;
use Framadate\Services\NotificationService;
use Framadate\Services\PollService;
use Framadate\Services\SessionService;
use Framadate\Utils;
include_once __DIR__ . '/app/inc/init.php';
@ -51,6 +52,7 @@ $adminPollService = new AdminPollService($connect, $pollService, $logService);
$inputService = new InputService();
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
$notificationService = new NotificationService($mailService);
$sessionService = new SessionService();
/* PAGE */
/* ---- */
@ -70,6 +72,18 @@ if ($poll) {
exit;
}
// -------------------------------
// creation message
// -------------------------------
$messagePollCreated = $sessionService->get("Framadate", "messagePollCreated", FALSE);
if ($messagePollCreated) {
$sessionService->remove("Framadate", "messagePollCreated");
$message = new Message('success', __('adminstuds', 'The poll is created.'));
}
// -------------------------------
// Update poll info
// -------------------------------
@ -201,6 +215,8 @@ if (!empty($_GET['vote'])) {
// Something to save (edit or add)
// -------------------------------
$selectedNewVotes = [];
if (!empty($_POST['save'])) { // Save edition of an old vote
$name = $inputService->filterName($_POST['name']);
$editedVote = filter_input(INPUT_POST, 'save', FILTER_VALIDATE_INT);
@ -223,6 +239,8 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
} else {
$message = new Message('danger', __('Error', 'Update vote failed'));
}
} catch (AlreadyExistsException $aee) {
$message = new Message('danger', __('Error', 'The name you\'ve chosen already exist in this poll!'));
} catch (ConcurrentEditionException $cee) {
$message = new Message('danger', __('Error', 'Poll has been updated before you vote'));
} catch (ConcurrentVoteException $cve) {
@ -252,6 +270,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
}
} catch (AlreadyExistsException $aee) {
$message = new Message('danger', __('Error', 'You already voted'));
$selectedNewVotes = $choices;
} catch (ConcurrentEditionException $cee) {
$message = new Message('danger', __('Error', 'Poll has been updated before you vote'));
} catch (ConcurrentVoteException $cve) {
@ -445,5 +464,6 @@ $smarty->assign('accessGranted', true);
$smarty->assign('resultPubliclyVisible', true);
$smarty->assign('editedVoteUniqueId', '');
$smarty->assign('default_to_marldown_editor', $config['markdown_editor_by_default']);
$smarty->assign('selectedNewVotes', $selectedNewVotes);
$smarty->display('studs.tpl');

View File

@ -85,4 +85,19 @@ class VoteRepository extends AbstractRepository {
$prepared->execute([$poll_id, $name]);
return $prepared->rowCount() > 0;
}
/**
* Check if name is already used for the given poll and another vote.
*
* @param int $poll_id ID of the poll
* @param string $name Name of the vote
* @param int $vote_id ID of the current vote
* @return bool true if vote already exists
*/
public function existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id) {
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND name = ? AND id != ?');
$prepared->execute([$poll_id, $name, $vote_id]);
return $prepared->rowCount() > 0;
}
}

View File

@ -88,24 +88,19 @@ class PollService {
* @param $name
* @param $choices
* @param $slots_hash
* @throws AlreadyExistsException
* @throws ConcurrentEditionException
* @throws ConcurrentVoteException
* @return bool
*/
public function updateVote($poll_id, $vote_id, $name, $choices, $slots_hash) {
$poll = $this->findById($poll_id);
// Check that no-one voted in the meantime and it conflicts the maximum votes constraint
$this->checkMaxVotes($choices, $poll, $poll_id);
// Check if slots are still the same
$this->checkThatSlotsDidntChanged($poll, $slots_hash);
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name, $vote_id);
// Update vote
$choices = implode($choices);
return $this->voteRepository->update($poll_id, $vote_id, $name, $choices);
}
/**
* @param $poll_id
* @param $name
@ -117,19 +112,8 @@ class PollService {
* @return \stdClass
*/
function addVote($poll_id, $name, $choices, $slots_hash) {
$poll = $this->findById($poll_id);
// Check that no-one voted in the meantime and it conflicts the maximum votes constraint
$this->checkMaxVotes($choices, $poll, $poll_id);
// Check if slots are still the same
$this->checkThatSlotsDidntChanged($poll, $slots_hash);
// Check if vote already exists
if ($this->voteRepository->existsByPollIdAndName($poll_id, $name)) {
throw new AlreadyExistsException();
}
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name);
// Insert new vote
$choices = implode($choices);
$token = $this->random(16);
@ -140,7 +124,8 @@ class PollService {
if ($this->commentRepository->exists($poll_id, $name, $comment)) {
return true;
}
return $this->commentRepository->insert($poll_id, $name, $comment);
return $this->commentRepository->insert($poll_id, $name, $comment);
}
/**
@ -307,7 +292,38 @@ class PollService {
private function random($length) {
return Token::getToken($length);
}
/**
* @param $choices
* @param $poll_id
* @param $slots_hash
* @param $name
* @param string $vote_id
* @throws AlreadyExistsException
* @throws ConcurrentVoteException
* @throws ConcurrentEditionException
*/
private function checkVoteConstraints($choices, $poll_id, $slots_hash, $name, $vote_id = FALSE) {
// Check if vote already exists with the same name
if (FALSE === $vote_id) {
$exists = $this->voteRepository->existsByPollIdAndName($poll_id, $name);
} else {
$exists = $this->voteRepository->existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id);
}
if ($exists) {
throw new AlreadyExistsException();
}
$poll = $this->findById($poll_id);
// Check that no-one voted in the meantime and it conflicts the maximum votes constraint
$this->checkMaxVotes($choices, $poll, $poll_id);
// Check if slots are still the same
$this->checkThatSlotsDidntChanged($poll, $slots_hash);
}
/**
* This method checks if the hash send by the user is the same as the computed hash.
*

View File

@ -18,7 +18,7 @@
*/
// FRAMADATE version
const VERSION = '1.1.0-beta.3';
const VERSION = '1.1.0-beta.4';
// PHP Needed version
const PHP_NEEDED_VERSION = '5.6';

View File

@ -21,6 +21,7 @@ use Framadate\Services\LogService;
use Framadate\Services\MailService;
use Framadate\Services\PollService;
use Framadate\Services\PurgeService;
use Framadate\Services\SessionService;
use Framadate\Utils;
include_once __DIR__ . '/app/inc/init.php';
@ -31,6 +32,7 @@ $logService = new LogService();
$pollService = new PollService($connect, $logService);
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
$purgeService = new PurgeService($connect, $logService);
$sessionService = new SessionService();
if (is_file('bandeaux_local.php')) {
include_once('bandeaux_local.php');
@ -108,6 +110,9 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
// Delete old polls
$purgeService->purgeOldPolls();
// creation message
$sessionService->set("Framadate", "messagePollCreated", TRUE);
// Redirect to poll administration
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
exit;

View File

@ -22,6 +22,7 @@ use Framadate\Services\LogService;
use Framadate\Services\MailService;
use Framadate\Services\PollService;
use Framadate\Services\PurgeService;
use Framadate\Services\SessionService;
use Framadate\Utils;
include_once __DIR__ . '/app/inc/init.php';
@ -33,6 +34,7 @@ $pollService = new PollService($connect, $logService);
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
$purgeService = new PurgeService($connect, $logService);
$inputService = new InputService();
$sessionService = new SessionService();
if (is_readable('bandeaux_local.php')) {
include_once('bandeaux_local.php');
@ -232,6 +234,9 @@ switch ($step) {
// Delete old polls
$purgeService->purgeOldPolls();
// creation message
$sessionService->set("Framadate", "messagePollCreated", TRUE);
// Redirect to poll administration
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
exit;

View File

@ -437,6 +437,7 @@
"Vote updated": "تم تحديث التصويت",
"You can add a new scheduling date to your poll.": "You can add a new scheduling date to your poll.",
"Your poll has been removed!": "Your poll has been removed!",
"The poll is created." : "The poll is created.",
"and add a new column with": "and add a new column with",
"remove a column or a line with": "remove a column or a line with"
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Hizivaet eo bet ar vouezh",
"You can add a new scheduling date to your poll.": "Gallout a rit ouzhpennañ un deiziad d'ho sontadeg.",
"Your poll has been removed!": "Dilamet eo bet ar sontadeg!",
"The poll is created." : "The poll is created.",
"and add a new column with": "ha m'ho peus disoñjet un dibab e c'hallit ouzhpennañ ur bann en ur glikañ war",
"remove a column or a line with": "dilemel ur bann pe ul linenn gant"
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Stimme aktualisiert",
"You can add a new scheduling date to your poll.": "Sie können Ihrer Umfrage ein neues Datum hinzufügen.",
"Your poll has been removed!": "Ihre Umfrage wurde gelöscht!",
"The poll is created." : "The poll is created.",
"and add a new column with": "und neue Spalte hinzufügen mit",
"remove a column or a line with": "Zeile oder Spalte entfernen mit"
},

View File

@ -438,6 +438,7 @@
"Vote updated": "Vote updated",
"You can add a new scheduling date to your poll.": "You can add a new scheduling date to your poll.",
"Your poll has been removed!": "Your poll has been removed!",
"The poll is created." : "The poll is created.",
"and add a new column with": "and add a new column with",
"remove a column or a line with": "remove a column or a line with"
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Voto actualizado",
"You can add a new scheduling date to your poll.": "Puede añadir una nueva fecha de encuentro a su encuesta.",
"Your poll has been removed!": "Su encuesta ha sido borrada",
"The poll is created." : "The poll is created.",
"and add a new column with": "y se puede añadir una columna con",
"remove a column or a line with": "borrar una columna o una fila con"
},

View File

@ -438,6 +438,7 @@
"Vote updated": "Vote mis à jour",
"You can add a new scheduling date to your poll.": "Vous pouvez ajouter une date à votre sondage.",
"Your poll has been removed!": "Votre sondage a été supprimé !",
"The poll is created." : "Le sondage est bien créé.",
"and add a new column with": "et si vous avez oublié de saisir un choix, vous pouvez rajouter une colonne en cliquant sur",
"remove a column or a line with": "effacer une colonne ou une ligne avec"
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Voto aggiornato",
"You can add a new scheduling date to your poll.": "Potete aggiungere una data al vostro sondaggio.",
"Your poll has been removed!": "Il vostro sondaggio è stato eliminato !",
"The poll is created." : "The poll is created.",
"and add a new column with": "e se vi foste dimenticati di inserire una scelta, potreste aggiungere una colonna cliccando su",
"remove a column or a line with": " cancellare una colonna o una riga con "
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Stem aangepast",
"You can add a new scheduling date to your poll.": "Je kan een nieuwe datum toevoegen aan je poll.",
"Your poll has been removed!": "Je poll is verwijderd!",
"The poll is created." : "The poll is created.",
"and add a new column with": "en voeg een nieuwe kokom toe met",
"remove a column or a line with": "verwijder een kolom of regel met"
},

View File

@ -437,6 +437,7 @@
"Vote updated": "Vòte mes a jorn",
"You can add a new scheduling date to your poll.": "Podètz apondre una data a vòstre sondatge.",
"Your poll has been removed!": "Vòstre sondatge es estat suprimit!",
"The poll is created." : "The poll is created.",
"and add a new column with": "E se avètz oblidat de picar una causida, podètz tornar apondre una colomna en clicant sus",
"remove a column or a line with": "escafar una colomna o una linha amb"
},

View File

@ -50,6 +50,7 @@ $resultPubliclyVisible = true;
$slots = [];
$votes = [];
$comments = [];
$selectedNewVotes = [];
/* Services */
/*----------*/
@ -145,7 +146,9 @@ if ($accessGranted) {
} else {
$message = new Message('danger', __('Error', 'Update vote failed'));
}
} catch (ConcurrentEditionException $cee) {
} catch (AlreadyExistsException $aee) {
$message = new Message('danger', __('Error', 'The name you\'ve chosen already exist in this poll!'));
} catch (ConcurrentEditionException $cee) {
$message = new Message('danger', __('Error', 'Poll has been updated before you vote'));
} catch (ConcurrentVoteException $cve) {
$message = new Message('danger', __('Error', "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry."));
@ -180,6 +183,7 @@ if ($accessGranted) {
}
} catch (AlreadyExistsException $aee) {
$message = new Message('danger', __('Error', 'You already voted'));
$selectedNewVotes = $choices;
} catch (ConcurrentEditionException $cee) {
$message = new Message('danger', __('Error', 'Poll has been updated before you vote'));
} catch (ConcurrentVoteException $cve) {
@ -237,5 +241,6 @@ $smarty->assign('accessGranted', $accessGranted);
$smarty->assign('resultPubliclyVisible', $resultPubliclyVisible);
$smarty->assign('editedVoteUniqueId', $editedVoteUniqueId);
$smarty->assign('ValueMax', $poll->ValueMax);
$smarty->assign('selectedNewVotes', $selectedNewVotes);
$smarty->display('studs.tpl');

View File

@ -180,26 +180,34 @@
<ul class="list-unstyled choice">
{if $poll->ValueMax eq NULL || $best_choices['y'][$i] lt $poll->ValueMax}
<li class="yes">
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" />
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2"
{(!isset($selectedNewVotes[$id]) || ("2" !== $selectedNewVotes[$id])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')|html} {$slot->title|html}">
<i class="glyphicon glyphicon-ok"></i><span class="sr-only">{__('Generic', 'Yes')}</span>
</label>
</li>
<li class="ifneedbe">
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1" />
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1"
{(!isset($selectedNewVotes[$id]) || ("1" !== $selectedNewVotes[$id])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slot->title|html}">
(<i class="glyphicon glyphicon-ok"></i>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span>
</label>
</li>
{/if}
<li class="no">
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0" />
<label class="btn btn-default btn-xs startunchecked" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slot->title|html}">
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0"
{(!isset($selectedNewVotes[$id]) || ("0" !== $selectedNewVotes[$id])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs {(!isset($selectedNewVotes[$id]) || ("0" !== $selectedNewVotes[$id])) ? "startunchecked" : ""}" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slot->title|html}">
<i class="glyphicon glyphicon-ban-circle"></i><span class="sr-only">{__('Generic', 'No')}</span>
</label>
</li>
<li class="hide">
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value=" " checked/>
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value=" "
{(isset($selectedNewVotes[$id]) || ("" !== $selectedNewVotes[$id])) ? "" : " checked"}
/>
</li>
</ul>
</td>

View File

@ -238,40 +238,43 @@
{foreach $slots as $slot}
{foreach $slot->moments as $moment}
<td class="bg-info" headers="M{$headersM[$i]} D{$headersD[$i]} H{$headersH[$i]}">
<ul class="list-unstyled choice">
{if $poll->ValueMax eq NULL || $best_choices['y'][$i] lt $poll->ValueMax}
<li class="yes">
<input type="radio" id="y-choice-{$i}" name="choices[{$i}]" value="2" />
<input type="radio" id="y-choice-{$i}" name="choices[{$i}]" value="2"
{(!isset($selectedNewVotes[$i]) || ("2" !== $selectedNewVotes[$i])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs" for="y-choice-{$i}" title="{__('Poll results', 'Vote yes for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
<i class="glyphicon glyphicon-ok"></i><span class="sr-only">{__('Generic', 'Yes')}</span>
</label>
</li>
<li class="ifneedbe">
<input type="radio" id="i-choice-{$i}" name="choices[{$i}]" value="1" />
<input type="radio" id="i-choice-{$i}" name="choices[{$i}]" value="1"
{(!isset($selectedNewVotes[$i]) || ("1" !== $selectedNewVotes[$i])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs" for="i-choice-{$i}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
(<i class="glyphicon glyphicon-ok"></i>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span>
</label>
</li>
{/if}
{/if}
<li class="no">
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value="0" />
<label class="btn btn-default btn-xs startunchecked" for="n-choice-{$i}" title="{__('Poll results', 'Vote no for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value="0"
{(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "" : " checked"}
/>
<label class="btn btn-default btn-xs {(!isset($selectedNewVotes[$i]) || ("0" !== $selectedNewVotes[$i])) ? "startunchecked" : ""}" for="n-choice-{$i}" title="{__('Poll results', 'Vote no for')|html} {$slot->day|date_format:$date_format.txt_short|html} - {$moment|html}">
<i class="glyphicon glyphicon-ban-circle"></i><span class="sr-only">{__('Generic', 'No')}</span>
</label>
</li>
<li class="hide">
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value=" " checked/>
<input type="radio" id="n-choice-{$i}" name="choices[{$i}]" value=" "
{(isset($selectedNewVotes[$i]) || ("" !== $selectedNewVotes[$i])) ? "" : " checked"}
/>
</li>
</ul>
</td>
{$i = $i+1}
{/foreach}
{/foreach}