From 7b0a619b0e10ad9e1d96fa38740a9821ff6079b0 Mon Sep 17 00:00:00 2001 From: Madeorsk Date: Thu, 16 Aug 2018 14:09:37 +0200 Subject: [PATCH] Multiple choices and redirections + Now possible to allow multiple choices; * Add partial settings support; * Fixed and moved some redirections to appropriate pages; * CSS adjustments. --- index.php | 33 +++++++++++++++++---------------- models/Poll.php | 32 ++++++++++++++++++++++++-------- static/css/common.css | 2 +- static/js/new.js | 7 ++++--- views/home.php | 5 +++++ views/poll.php | 2 +- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/index.php b/index.php index 5efeb78..6edc20f 100644 --- a/index.php +++ b/index.php @@ -41,8 +41,14 @@ Flight::route("GET /polls/@id:[a-fA-F0-9]+", function ($id) { Flight::json(format_poll($poll)); else { - Flight::render("poll", ["poll" => $poll], "body_content"); - Flight::render("layout"); + // If unique_ip option is enabled => Only allow unregistered IPs. + if (!$poll->settings->unique_ip && isset($poll->ips[Flight::request()->ip])) + Flight::redirect("/polls/$id/results"); // A vote is already registered with this IP: redirect. + else + { + Flight::render("poll", ["poll" => $poll], "body_content"); + Flight::render("layout"); + } } } else @@ -59,17 +65,14 @@ Flight::route("POST /polls/@id:[a-fA-F0-9]+/vote", function ($id) { { if (isset(Flight::request()->data["options"]) && is_array(Flight::request()->data["options"])) { // Check that an options id array exists. - //TODO Check that only the authorized number of options are selected. - if($poll->vote(Flight::request()->data["options"]) === false) // Vote for the given options. - { - Flight::halt(403, "

403 Forbidden

Too many votes for this IP address.

"); - } - else + if ($poll->vote(Flight::request()->data["options"])) // Vote for the given options. { // Then save and show poll data. $poll->save(); Flight::json(format_poll($poll)); } + else + Flight::halt(403, "

403 Forbidden

Too many votes for this IP address or too many options selected.

"); } else Flight::halt(403, "

403 Forbidden

Invalid data.

"); @@ -79,18 +82,16 @@ Flight::route("POST /polls/@id:[a-fA-F0-9]+/vote", function ($id) { if (isset(Flight::request()->data["options"])) { // Check that any data has been sent. $selected_options = Flight::request()->data["options"]; - if (is_string($selected_options)) - { // If it is a string, input[type="radio"] were used so only one option is selected. - if($poll->vote([intval($selected_options)]) === false) // Vote for the selected option. - { - Flight::redirect('/', 401); - } - else + if (is_array($selected_options)) + { + if($poll->vote($selected_options)) // Vote for the selected option. { $poll->save(); Flight::redirect("/polls/$id/results"); // Redirect to the results. } - } //TODO: Multiple options case. + else + Flight::redirect("/polls/$id"); // Error: Redirect to the vote page. + } else Flight::redirect("/polls/$id"); // Error: Redirect to the vote page. } diff --git a/models/Poll.php b/models/Poll.php index 1edc25a..201e401 100644 --- a/models/Poll.php +++ b/models/Poll.php @@ -4,6 +4,16 @@ require __DIR__ . "/../config/app.php"; define("SAVE_PATH", __DIR__ . "/../db"); +define("DEFAULT_SETTINGS", ["unique_ip" => true, "multiple_choices" => false]); + +function settings_or_default($settings) +{ + return [ + "unique_ip" => isset($settings["unique_ip"]) ? $settings["unique_ip"] : DEFAULT_SETTINGS["unique_ip"], + "multiple_choices" => isset($settings["multiple_choices"]) ? $settings["multiple_choices"] : DEFAULT_SETTINGS["multiple_choices"], + ]; +} + class Poll { /** @@ -23,7 +33,7 @@ class Poll "votes" => 0, ]; } - $poll->settings = $request_data->settings; + $poll->settings = isset($request_data->settings) ? settings_or_default($request_data->settings) : DEFAULT_SETTINGS; $poll->gen_new_id(); $poll->delete_token = bin2hex(openssl_random_pseudo_bytes(16)); $poll->save(); @@ -70,7 +80,7 @@ class Poll public $title; public $creation_date; public $options = []; - public $settings = []; + public $settings; public $ips = []; public $delete_token; @@ -98,14 +108,20 @@ class Poll */ public function vote(array $options) { - if($this->settings->unique_ip === false) - { - if(isset($this->ips[Flight::request()->ip])) - return false; + if (empty($options)) + return false; // Disallow void selection vote. TODO: Allow it in settings? + + if (!$this->settings->unique_ip) + { // If unique_ip option is enabled => Only allow unregistered IPs. + if (isset($this->ips[Flight::request()->ip])) + return false; // A vote is already registered with this IP: error. else - $this->ips[Flight::request()->ip] = true; + $this->ips[Flight::request()->ip] = true; // We register the IP in the used IPs array. } + if (!$this->settings->multiple_choices && count($options) > 1) + return false; // If multiple_choices is not selected, disallow an options array with more than one selected option. + // For each option in the list, add 1 to the vote number in the poll data. foreach ($options as $option) if (isset($this->options[intval($option)])) // Check invalid options id. @@ -125,7 +141,7 @@ class Poll "options" => $this->options, "delete_token" => $this->delete_token, "ips" => $this->ips, - "settings" => $this->settings + "settings" => $this->settings, ]), $db); dba_close($db); } diff --git a/static/css/common.css b/static/css/common.css index 049441e..a93de49 100644 --- a/static/css/common.css +++ b/static/css/common.css @@ -83,7 +83,7 @@ main a.button:hover main hr { - border: solid #343434 thin; + border: solid #0088E5 thin; width: 25rem; } diff --git a/static/js/new.js b/static/js/new.js index 7a95d90..4380b3a 100644 --- a/static/js/new.js +++ b/static/js/new.js @@ -37,9 +37,10 @@ document.addEventListener("DOMContentLoaded", () => { body: JSON.stringify({ title: form.querySelector(`input[name="title"]`).value, options: get_choices(form), - settings: { - "unique_ip": form.querySelector(`input[name="unique_ip"]`).checked, - } + settings: { + unique_ip: form.querySelector(`input[name="unique_ip"]`).checked, + multiple_choices: form.querySelector(`input[name="multiple_choices"]`).checked, + } }), headers: { "Content-Type": "application/json", diff --git a/views/home.php b/views/home.php index f4b952b..016bbc4 100644 --- a/views/home.php +++ b/views/home.php @@ -15,6 +15,11 @@ +
+ + + +