From ff47a21ac292b190a4558256a9ef761e91536033 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 20 Feb 2018 16:47:10 +0100 Subject: [PATCH] Check that conditions on valueMax are acceptable before adding the vote Handles people voting when the answers valueMax has been reached by someone else in the background Signed-off-by: Thomas Citharel --- adminstuds.php | 5 +++ .../Exception/ConcurrentVoteException.php | 12 +++++ .../Framadate/Services/PollService.php | 45 +++++++++++++++++++ locale/br.json | 1 + locale/de.json | 1 + locale/en.json | 1 + locale/es.json | 1 + locale/fr.json | 1 + locale/it.json | 1 + locale/nl.json | 1 + locale/oc.json | 3 +- studs.php | 5 +++ 12 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 app/classes/Framadate/Exception/ConcurrentVoteException.php diff --git a/adminstuds.php b/adminstuds.php index 0d03059..74a205a 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -19,6 +19,7 @@ use Framadate\Editable; use Framadate\Exception\AlreadyExistsException; use Framadate\Exception\ConcurrentEditionException; +use Framadate\Exception\ConcurrentVoteException; use Framadate\Exception\MomentAlreadyExistsException; use Framadate\Message; use Framadate\Security\PasswordHasher; @@ -224,6 +225,8 @@ if (!empty($_POST['save'])) { // Save edition of an old vote } } 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.")); } } } elseif (isset($_POST['save'])) { // Add a new vote @@ -251,6 +254,8 @@ if (!empty($_POST['save'])) { // Save edition of an old vote $message = new Message('danger', __('Error', 'You already voted')); } 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.")); } } } diff --git a/app/classes/Framadate/Exception/ConcurrentVoteException.php b/app/classes/Framadate/Exception/ConcurrentVoteException.php new file mode 100644 index 0000000..26b29ec --- /dev/null +++ b/app/classes/Framadate/Exception/ConcurrentVoteException.php @@ -0,0 +1,12 @@ +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); @@ -93,9 +107,22 @@ class PollService { return $this->voteRepository->update($poll_id, $vote_id, $name, $choices); } + /** + * @param $poll_id + * @param $name + * @param $choices + * @param $slots_hash + * @return \stdClass + * @throws AlreadyExistsException + * @throws ConcurrentEditionException + * @throws ConcurrentVoteException + */ 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); @@ -252,4 +279,22 @@ class PollService { throw new ConcurrentEditionException(); } } + + /** + * This method checks if the votes doesn't conflicts the maximum votes constraint + * + * @param $user_choice + * @param \stdClass $poll + * @param string $poll_id + * @throws ConcurrentVoteException + */ + private function checkMaxVotes($user_choice, $poll, $poll_id) { + $best_choices = $this->computeBestChoices($this->allVotesByPollId($poll_id)); + foreach ($best_choices['y'] as $i => $nb_choice) { + // if for this option we have reached maximum value and user wants to add itself too + if ($nb_choice >= $poll->ValueMax && $user_choice[$i] === "2") { + throw new ConcurrentVoteException(); + } + } + } } diff --git a/locale/br.json b/locale/br.json index 9f8990a..b20e00e 100644 --- a/locale/br.json +++ b/locale/br.json @@ -395,6 +395,7 @@ "Adding vote failed": "C'hwitadenn war ouzhpennadenn ar vouezh", "You already voted": "Mouezhzt ho peus endeo", "Poll has been updated before you vote": "Hizivaet eo bet ar sontadeg a-raok ho mouezh", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "C'hiwtadenn war an evezhiadenn", "You can't create a poll with hidden results with the following edition option:": "N'hallit ket krouiñ ur sontadeg gant respontoù kuzhet gant an dibarzhioù embann da heul:", "Failed to delete column": "C'hwitadenn war zilemel ar bann", diff --git a/locale/de.json b/locale/de.json index 8b32bb7..1e100a5 100644 --- a/locale/de.json +++ b/locale/de.json @@ -396,6 +396,7 @@ "Adding vote failed": "Stimmabgabe fehlgeschlagen", "You already voted": "Sie haben bereits abgestimmt", "Poll has been updated before you vote": "Die Abstimmung wurde vor Ihrer Stimmabgabe aktualisiert", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "Abgabe des Kommentars gescheitert", "You can't create a poll with hidden results with the following edition option:": "Sie können mit der folgenden Editier-Option keine Umfrage mit versteckten Ergebnissen erzeugen:", "Failed to delete column": "Löschen der Spalte fehlgeschlagen", diff --git a/locale/en.json b/locale/en.json index c412a76..c487a84 100644 --- a/locale/en.json +++ b/locale/en.json @@ -399,6 +399,7 @@ "Adding vote failed": "Adding vote failed", "You already voted": "You already voted", "Poll has been updated before you vote": "Poll has been updated before you vote", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "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 option: ", "Failed to delete column": "Failed to delete column", diff --git a/locale/es.json b/locale/es.json index a267524..3c0ebc9 100644 --- a/locale/es.json +++ b/locale/es.json @@ -396,6 +396,7 @@ "Adding vote failed": "Error al crear el voto", "You already voted": "Usted ya votó", "Poll has been updated before you vote": "La encuesta fue actualizada antes de su voto", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "Error al crear el comentario", "You can't create a poll with hidden results with the following edition option:": "No puede crear una encuesta con resultados no visibles con los siguientes opciones de edición", "Failed to delete column": "Error al eliminar la columna", diff --git a/locale/fr.json b/locale/fr.json index 6486504..1de86bb 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -399,6 +399,7 @@ "Adding vote failed": "Échec de l'ajout d'un vote", "You already voted": "Vous avez déjà voté", "Poll has been updated before you vote": "Le sondage a été mis à jour avant votre vote", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Votre vote n'a pas été pris en compte, car quelqu'un a voté entre temps et cela entre en conflit avec vos choix et les conditions du sondage. Merci de réessayer.", "Comment failed": "Échec du commentaire", "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'édition suivantes : ", "Failed to delete column": "Échec de la suppression de colonne", diff --git a/locale/it.json b/locale/it.json index 112a881..83f1368 100644 --- a/locale/it.json +++ b/locale/it.json @@ -396,6 +396,7 @@ "Adding vote failed": "Aggiunta del voto fallito", "You already voted": "IT_Vous avez déjà voté", "Poll has been updated before you vote": "IT_Le sondage a été mis à jour avant votre vote", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "Commento fallito", "You can't create a poll with hidden results with the following edition option:": "Non potete creare un sondaggio con i risultati nascosti con queste opzioni: ", "Failed to delete column": "Impossibile eliminare la colonna", diff --git a/locale/nl.json b/locale/nl.json index 3f17a53..14499e0 100644 --- a/locale/nl.json +++ b/locale/nl.json @@ -396,6 +396,7 @@ "Adding vote failed": "Toevoegen stem gefaald", "You already voted": "Je hebt al gestemd", "Poll has been updated before you vote": "De poll is gewijzigd voordat je stemde", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "Opmerking mislukt", "You can't create a poll with hidden results with the following edition option:": "Je kan geen poll met verborgen resultaten maken met de volgende optie: ", "Failed to delete column": "Kolom verwijderen mislukt", diff --git a/locale/oc.json b/locale/oc.json index e2a9811..8bdac4b 100644 --- a/locale/oc.json +++ b/locale/oc.json @@ -396,6 +396,7 @@ "Adding vote failed": "Fracàs de l’apondon d’un vòte", "You already voted": "Avètz ja votat", "Poll has been updated before you vote": "Lo sondatge es estat mes a jorn abans vòstre vòte", + "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.": "Your vote wasn't counted, because someone voted in the meantime and it conflicted with your choices and the poll conditions. Please retry.", "Comment failed": "Fracàs del comentari", "You can't create a poll with hidden results with the following edition option:": "Podètz pas crear de sondatges amb de resultats amagats amb las opcions d’edicion seguentas : ", "Failed to delete column": "Fracàs de la supression de colomna", @@ -428,4 +429,4 @@ "Check again": "Tornar verificar", "Continue the installation": "Contunhar l’installacion" } -} \ No newline at end of file +} diff --git a/studs.php b/studs.php index 64d1a89..b9a30b2 100644 --- a/studs.php +++ b/studs.php @@ -19,6 +19,7 @@ use Framadate\Editable; use Framadate\Exception\AlreadyExistsException; use Framadate\Exception\ConcurrentEditionException; +use Framadate\Exception\ConcurrentVoteException; use Framadate\Message; use Framadate\Security\Token; use Framadate\Services\InputService; @@ -146,6 +147,8 @@ if ($accessGranted) { } } 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.")); } } } elseif (isset($_POST['save'])) { // Add a new vote @@ -179,6 +182,8 @@ if ($accessGranted) { $message = new Message('danger', __('Error', 'You already voted')); } 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.")); } } }