From e0b8842349e6c8cf630c7b7f8e805e09147222a4 Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 11:54:40 +0200 Subject: [PATCH 01/18] Updating composer.lock. - It's good practice : https://stackoverflow.com/questions/12896780/should-composer-lock-be-committed-to-version-control . --- composer.lock | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 14618a2..7997006 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "4771fa2616869cff821e2bf1daa6245c", + "hash": "35bdfd24b481ad94a99b6fd67499aba9", "packages": [ { "name": "o80/i18n", @@ -12,12 +12,12 @@ "source": { "type": "git", "url": "https://github.com/olivierperez/o80-i18n.git", - "reference": "830112445b557068b9fe02b576d5cf770fcdf037" + "reference": "669befcdadf3a745193792f51e97af1e70b3e614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/olivierperez/o80-i18n/zipball/830112445b557068b9fe02b576d5cf770fcdf037", - "reference": "830112445b557068b9fe02b576d5cf770fcdf037", + "url": "https://api.github.com/repos/olivierperez/o80-i18n/zipball/669befcdadf3a745193792f51e97af1e70b3e614", + "reference": "669befcdadf3a745193792f51e97af1e70b3e614", "shasum": "" }, "require": { @@ -50,9 +50,7 @@ "internationalization", "php" ], - "time": "2015-03-21 22:37:40" - "time": "2015-03-27 19:37:27" - "time": "2015-03-23 21:40:47" + "time": "2015-03-30 22:20:26" }, { "name": "smarty/smarty", From 09ca8b28a7d806eae493f9a6416adc4e8b1c2b47 Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 11:57:12 +0200 Subject: [PATCH 02/18] Added smarty developer configuration. --- app/inc/smarty.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/inc/smarty.php b/app/inc/smarty.php index c9bad47..7481e78 100644 --- a/app/inc/smarty.php +++ b/app/inc/smarty.php @@ -34,6 +34,16 @@ $smarty->assign('html_lang', $html_lang); $smarty->assign('langs', $ALLOWED_LANGUAGES); $smarty->assign('date_format', $date_format); +if ($_SERVER['FRAMADATE_DEVMODE']) { + $smarty->force_compile = true; + $smarty->compile_check = true; + +} else { + $smarty->force_compile = false; + $smarty->compile_check = false; +} + + function smarty_modifier_poll_url($poll_id, $admin = false) { return Utils::getUrlSondage($poll_id, $admin); } From c4cc36b076b8977202ba5bec2aa610b7b318bb8d Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 11:58:35 +0200 Subject: [PATCH 03/18] Using more secure token --- app/classes/Framadate/Security/Token.php | 60 +++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/app/classes/Framadate/Security/Token.php b/app/classes/Framadate/Security/Token.php index 7222dbf..b4a4b9b 100644 --- a/app/classes/Framadate/Security/Token.php +++ b/app/classes/Framadate/Security/Token.php @@ -5,14 +5,17 @@ class Token { private $time; private $value; + private $length; + private static $codeAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'; - function __construct() { + function __construct($length = 64) { + $this->length = $length; $this->time = time() + TOKEN_TIME; $this->value = $this->generate(); } private function generate() { - return sha1(uniqid(mt_rand(), true)); + return self::getToken($this->length); } public function getTime() { @@ -31,5 +34,58 @@ class Token { return $value === $this->value; } + /** + * Get a secure token if possible, or a less secure one if not. + * + * @param int $length The token length + * @param bool $crypto_strong If passed, tells if the token is "cryptographically strong" or not. + * @return string + */ + public static function getToken($length, &$crypto_strong = false) { + if (function_exists('openssl_random_pseudo_bytes')) { + openssl_random_pseudo_bytes(1, $crypto_strong); // Fake use to see if the algorithm used was "cryptographically strong" + return self::getSecureToken($length); + } + return self::getUnsecureToken($length); + } + + public static function getUnsecureToken($length) { + $string = ''; + mt_srand(); + for ($i = 0; $i < $length; $i++) { + $string .= self::$codeAlphabet[mt_rand() % strlen(self::$codeAlphabet)]; + } + + return $string; + } + + /** + * @author http://stackoverflow.com/a/13733588 + */ + public static function getSecureToken($length){ + $token = ""; + for($i=0;$i<$length;$i++){ + $token .= self::$codeAlphabet[self::crypto_rand_secure(0,strlen(self::$codeAlphabet))]; + } + return $token; + } + + /** + * @author http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322 + */ + private static function crypto_rand_secure($min, $max) { + $range = $max - $min; + if ($range < 0) return $min; // not so random... + $log = log($range, 2); + $bytes = (int) ($log / 8) + 1; // length in bytes + $bits = (int) $log + 1; // length in bits + $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 + do { + $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); + $rnd = $rnd & $filter; // discard irrelevant bits + } while ($rnd >= $range); + return $min + $rnd; + } + } \ No newline at end of file From 86a89abf4297fedac031d25fa52322d1446807c0 Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 11:58:47 +0200 Subject: [PATCH 04/18] Added unique id to vote. --- admin/migration.php | 4 +- app/classes/Framadate/FramaDB.php | 7 +- .../AddColumn_uniqId_In_vote_For_0_9.php | 79 +++++++++++++++++++ .../Framadate/Services/PollService.php | 18 ++--- app/inc/constants.php | 2 +- 5 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php diff --git a/admin/migration.php b/admin/migration.php index 1551e9d..f60d9ce 100644 --- a/admin/migration.php +++ b/admin/migration.php @@ -20,6 +20,7 @@ use Framadate\Migration\From_0_0_to_0_8_Migration; use Framadate\Migration\From_0_8_to_0_9_Migration; use Framadate\Migration\AddColumn_receiveNewComments_For_0_9; +use Framadate\Migration\AddColumn_uniqId_In_vote_For_0_9; use Framadate\Migration\Migration; use Framadate\Utils; @@ -31,7 +32,8 @@ set_time_limit(300); $migrations = [ new From_0_0_to_0_8_Migration(), new From_0_8_to_0_9_Migration(), - new AddColumn_receiveNewComments_For_0_9() + new AddColumn_receiveNewComments_For_0_9(), + new AddColumn_uniqId_In_vote_For_0_9() ]; // --------------------------------------- diff --git a/app/classes/Framadate/FramaDB.php b/app/classes/Framadate/FramaDB.php index d9743be..ba1b250 100644 --- a/app/classes/Framadate/FramaDB.php +++ b/app/classes/Framadate/FramaDB.php @@ -122,15 +122,16 @@ class FramaDB { return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]); } - function insertVote($poll_id, $name, $choices) { - $prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices) VALUES (?,?,?)'); - $prepared->execute([$poll_id, $name, $choices]); + function insertVote($poll_id, $name, $choices, $token) { + $prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices, uniqId) VALUES (?,?,?,?)'); + $prepared->execute([$poll_id, $name, $choices, $token]); $newVote = new \stdClass(); $newVote->poll_id = $poll_id; $newVote->id = $this->pdo->lastInsertId(); $newVote->name = $name; $newVote->choices = $choices; + $newVote->token = $token; return $newVote; } diff --git a/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php b/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php new file mode 100644 index 0000000..9f50e4a --- /dev/null +++ b/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php @@ -0,0 +1,79 @@ +query('SHOW TABLES'); + $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN); + + // Check if tables of v0.9 are presents + $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables); + return count($diff) === 0; + } + + /** + * This methode is called only one time in the migration page. + * + * @param \PDO $pdo The connection to database + * @return bool true is the execution succeeded + */ + function execute(\PDO $pdo) { + $this->alterPollTable($pdo); + + return true; + } + + private function alterPollTable(\PDO $pdo) { + $pdo->exec(' + ALTER TABLE `' . Utils::table('vote') . '` + ADD `uniqId` CHAR(16) NOT NULL + AFTER `id`, + ADD INDEX (`uniqId`) ;'); + } + +} diff --git a/app/classes/Framadate/Services/PollService.php b/app/classes/Framadate/Services/PollService.php index cf32713..0fd397f 100644 --- a/app/classes/Framadate/Services/PollService.php +++ b/app/classes/Framadate/Services/PollService.php @@ -21,6 +21,7 @@ namespace Framadate\Services; use Framadate\Form; use Framadate\FramaDB; use Framadate\Utils; +use Framadate\Security\Token; class PollService { @@ -66,8 +67,8 @@ class PollService { function addVote($poll_id, $name, $choices) { $choices = implode($choices); - - return $this->connect->insertVote($poll_id, $name, $choices); + $token = $this->random(16); + return $this->connect->insertVote($poll_id, $name, $choices, $token); } function addComment($poll_id, $name, $comment) { @@ -176,15 +177,8 @@ class PollService { return [$poll_id, $admin_poll_id]; } - private function random($car) { - // TODO Better random ? - $string = ''; - $chaine = 'abcdefghijklmnopqrstuvwxyz123456789'; - mt_srand(); - for ($i = 0; $i < $car; $i++) { - $string .= $chaine[mt_rand() % strlen($chaine)]; - } - - return $string; + private function random($length) { + return Token::getToken($length); } + } diff --git a/app/inc/constants.php b/app/inc/constants.php index 60bab3c..fb5b618 100644 --- a/app/inc/constants.php +++ b/app/inc/constants.php @@ -21,7 +21,7 @@ const VERSION = '0.9'; // Regex -const POLL_REGEX = '/^[a-z0-9]+$/'; +const POLL_REGEX = '/^[a-zA-Z0-9]+$/'; const CHOICE_REGEX = '/^[012]$/'; const NAME_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9_ -]+$/i'; const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/'; From 4c137748b48ae567f11ef1ce9e65fe4141553f4b Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 16:52:46 +0200 Subject: [PATCH 05/18] Editing vote by link with unique id - Changed the smarty modifier poll_url to a function and added the vote_id parameter - Modified accordingly all poll_url occurence in templates - Added htaccess.txt to be sure to keep poll's URL changes up to date - Escaped some templates output in order to avoid to broke HTML - Using vote's uniqId instead of vote's id when it's needed --- adminstuds.php | 18 ++++++++----- .../Framadate/Services/PollService.php | 1 + app/classes/Framadate/Utils.php | 17 ++++++++---- app/inc/smarty.php | 11 ++++++-- htaccess.txt | 13 ++++++++++ studs.php | 12 ++++++--- tpl/add_slot.tpl | 2 +- tpl/admin/polls.tpl | 4 +-- tpl/confirm/delete_comments.tpl | 2 +- tpl/confirm/delete_poll.tpl | 2 +- tpl/confirm/delete_votes.tpl | 2 +- tpl/index.tpl | 2 +- tpl/part/poll_info.tpl | 10 +++---- tpl/part/vote_table_classic.tpl | 26 +++++++++---------- tpl/part/vote_table_date.tpl | 10 +++---- 15 files changed, 84 insertions(+), 48 deletions(-) create mode 100644 htaccess.txt diff --git a/adminstuds.php b/adminstuds.php index 38c92bf..b7fe959 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -45,10 +45,16 @@ $inputService = new InputService(); /* PAGE */ /* ---- */ -if (!empty($_GET['poll']) && strlen($_GET['poll']) === 24) { - $admin_poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); - $poll_id = substr($admin_poll_id, 0, 16); - $poll = $pollService->findById($poll_id); +if (!empty($_POST['poll']) || !empty($_GET['poll'])) { + if (!empty($_POST['poll'])) + $inputType = INPUT_POST; + else + $inputType = INPUT_GET; + $admin_poll_id = filter_input($inputType, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + if (strlen($admin_poll_id) === 24) { + $poll_id = substr($admin_poll_id, 0, 16); + $poll = $pollService->findById($poll_id); + } } if (!$poll) { @@ -131,8 +137,8 @@ if (isset($_POST['update_poll_info'])) { // A vote is going to be edited // ------------------------------- -if (!empty($_POST['edit_vote'])) { - $editingVoteId = filter_input(INPUT_POST, 'edit_vote', FILTER_VALIDATE_INT); +if (!empty($_GET['vote'])) { + $editingVoteId = filter_input(INPUT_GET, 'vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); } // ------------------------------- diff --git a/app/classes/Framadate/Services/PollService.php b/app/classes/Framadate/Services/PollService.php index 0fd397f..ad5a1e2 100644 --- a/app/classes/Framadate/Services/PollService.php +++ b/app/classes/Framadate/Services/PollService.php @@ -116,6 +116,7 @@ class PollService { $obj = new \stdClass(); $obj->id = $vote->id; $obj->name = $vote->name; + $obj->uniqId = $vote->uniqId; $obj->choices = str_split($vote->choices); $splitted[] = $obj; diff --git a/app/classes/Framadate/Utils.php b/app/classes/Framadate/Utils.php index 7491c4f..6a91a27 100644 --- a/app/classes/Framadate/Utils.php +++ b/app/classes/Framadate/Utils.php @@ -97,23 +97,30 @@ class Utils { } /** - * Fonction permettant de générer les URL pour les sondage - * @param string $id L'identifiant du sondage - * @param bool $admin True pour générer une URL pour l'administration d'un sondage, False pour un URL publique - * @return string L'url pour le sondage + * Function allowing to generate poll's url + * @param string $id The poll's id + * @param bool $admin True to generate an admin URL, false for a public one + * @param string $vote_id (optional) The vote's unique id + * @return string The poll's URL. */ - public static function getUrlSondage($id, $admin = false) { + public static function getUrlSondage($id, $admin = false, $vote_id='') { if (URL_PROPRE) { if ($admin === true) { $url = str_replace('/admin', '', self::get_server_name()) . $id . '/admin'; } else { $url = str_replace('/admin', '', self::get_server_name()) . $id; + if ($vote_id != '') { + $url .= '/vote/'.$vote_id; + } } } else { if ($admin === true) { $url = str_replace('/admin', '', self::get_server_name()) . 'adminstuds.php?poll=' . $id; } else { $url = str_replace('/admin', '', self::get_server_name()) . 'studs.php?poll=' . $id; + if ($vote_id != '') { + $url .= '&vote='.$vote_id; + } } } diff --git a/app/inc/smarty.php b/app/inc/smarty.php index 7481e78..87e8046 100644 --- a/app/inc/smarty.php +++ b/app/inc/smarty.php @@ -34,6 +34,7 @@ $smarty->assign('html_lang', $html_lang); $smarty->assign('langs', $ALLOWED_LANGUAGES); $smarty->assign('date_format', $date_format); +// Dev Mode if ($_SERVER['FRAMADATE_DEVMODE']) { $smarty->force_compile = true; $smarty->compile_check = true; @@ -44,8 +45,14 @@ if ($_SERVER['FRAMADATE_DEVMODE']) { } -function smarty_modifier_poll_url($poll_id, $admin = false) { - return Utils::getUrlSondage($poll_id, $admin); +function smarty_function_poll_url($params, Smarty_Internal_Template $template) { + $poll_id = filter_var($params['id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + $admin = $params['admin']?true:false; + $vote_unique_id = filter_var($params['vote_id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + + // If filter_var fails (i.e.: hack tentative), it will return false. At least no leak is possible from this. + + return Utils::getUrlSondage($poll_id, $admin, $vote_unique_id); } function smarty_modifier_markdown($md, $clear = false) { diff --git a/htaccess.txt b/htaccess.txt new file mode 100644 index 0000000..8b223e9 --- /dev/null +++ b/htaccess.txt @@ -0,0 +1,13 @@ +###################### +# .htaccess example. # +###################### + + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} -f [OR] + RewriteCond %{REQUEST_FILENAME} -d + + RewriteRule ^([a-zA-Z0-9]{16})$ studs.php?poll=$1 + RewriteRule ^([a-zA-Z0-9]{16})/vote/([a-zA-Z0-9]{16})$ studs.php?poll=$1&vote_id=$2 + RewriteRule ^([a-zA-Z0-9]{24})/admin$ adminstuds.php?poll=$1 + \ No newline at end of file diff --git a/studs.php b/studs.php index 461d86d..c965917 100644 --- a/studs.php +++ b/studs.php @@ -91,8 +91,12 @@ function sendUpdateNotification($poll, $mailService, $name, $type) { /* PAGE */ /* ---- */ -if (!empty($_GET['poll'])) { - $poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); +if (!empty($_POST['poll']) || !empty($_GET['poll'])) { + if (!empty($_POST['poll'])) + $inputType = INPUT_POST; + else + $inputType = INPUT_GET; + $poll_id = filter_input($inputType, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); $poll = $pollService->findById($poll_id); } @@ -106,8 +110,8 @@ if (!$poll) { // A vote is going to be edited // ------------------------------- -if (!empty($_POST['edit_vote'])) { - $editingVoteId = filter_input(INPUT_POST, 'edit_vote', FILTER_VALIDATE_INT); +if (!empty($_GET['vote'])) { + $editingVoteId = filter_input(INPUT_GET, 'vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); } // ------------------------------- diff --git a/tpl/add_slot.tpl b/tpl/add_slot.tpl index a8593e1..3ef5e5e 100644 --- a/tpl/add_slot.tpl +++ b/tpl/add_slot.tpl @@ -1,7 +1,7 @@ {extends file='page.tpl'} {block name=main} -
+

{__('adminstuds', 'Column\'s adding')}

diff --git a/tpl/admin/polls.tpl b/tpl/admin/polls.tpl index e26e3ae..53bbd1f 100644 --- a/tpl/admin/polls.tpl +++ b/tpl/admin/polls.tpl @@ -91,11 +91,11 @@ {/if} {$poll->votes|html} {$poll->id|html} - {__('Admin', 'See the poll')} - {__('Admin', 'Change the poll')} diff --git a/tpl/confirm/delete_comments.tpl b/tpl/confirm/delete_comments.tpl index c94bf10..bd9642f 100644 --- a/tpl/confirm/delete_comments.tpl +++ b/tpl/confirm/delete_comments.tpl @@ -1,7 +1,7 @@ {extends file='page.tpl'} {block name=main} - +

{__('adminstuds', 'Confirm removal of all comments of the poll')}

diff --git a/tpl/confirm/delete_poll.tpl b/tpl/confirm/delete_poll.tpl index 9db0777..7bba15a 100644 --- a/tpl/confirm/delete_poll.tpl +++ b/tpl/confirm/delete_poll.tpl @@ -1,7 +1,7 @@ {extends file='page.tpl'} {block name=main} - +

{__('adminstuds', 'Confirm removal of the poll')}

diff --git a/tpl/confirm/delete_votes.tpl b/tpl/confirm/delete_votes.tpl index ed863b1..38faf64 100644 --- a/tpl/confirm/delete_votes.tpl +++ b/tpl/confirm/delete_votes.tpl @@ -1,7 +1,7 @@ {extends file='page.tpl'} {block name=main} - +

{__('adminstuds', 'Confirm removal of all votes of the poll')}

diff --git a/tpl/index.tpl b/tpl/index.tpl index d3af42b..c7b20a5 100644 --- a/tpl/index.tpl +++ b/tpl/index.tpl @@ -51,7 +51,7 @@ {if $demo_poll != null}

{__('1st section', 'Do you want to')} - {__('1st section', 'view an example?')} + {__('1st section', 'view an example?')}

{/if}
diff --git a/tpl/part/poll_info.tpl b/tpl/part/poll_info.tpl index 93e43b6..b39d1c9 100644 --- a/tpl/part/poll_info.tpl +++ b/tpl/part/poll_info.tpl @@ -1,6 +1,6 @@ {$admin = $admin|default:false} -{if $admin}{/if} +{if $admin}{/if}
@@ -90,13 +90,13 @@
{if $admin}

{__('PollInfo', 'Expiration date')}

diff --git a/tpl/part/vote_table_classic.tpl b/tpl/part/vote_table_classic.tpl index 2c3a48b..f94e169 100644 --- a/tpl/part/vote_table_classic.tpl +++ b/tpl/part/vote_table_classic.tpl @@ -5,7 +5,7 @@

{__('Poll results', 'Votes of the poll')}

- + @@ -35,8 +35,7 @@ {* Edited line *} - {if $editingVoteId == $vote->id} - + {if $editingVoteId === $vote->uniqId} {else} - {* Voted line *} @@ -90,11 +88,11 @@ {if $active && $poll->editable && !$expired} {/foreach} - {else} + {elseif !$hidden} {* Voted line *} @@ -193,57 +193,60 @@ {/if} - {* Line displaying best moments *} - {$count_bests = 0} - {$max = max($best_choices)} - {if $max > 0} - - - {foreach $best_choices as $best_moment} - {if $max == $best_moment} - {$count_bests = $count_bests +1} - - {elseif $best_moment > 0} - - {else} - - {/if} - {/foreach} - + {if !$hidden} + {* Line displaying best moments *} + {$count_bests = 0} + {$max = max($best_choices)} + {if $max > 0} + + + {foreach $best_choices as $best_moment} + {if $max == $best_moment} + {$count_bests = $count_bests +1} + + {elseif $best_moment > 0} + + {else} + + {/if} + {/foreach} + + {/if} {/if}
{__('Poll results', 'Votes of the poll')} {$poll->title|html}
@@ -50,19 +49,19 @@
  • -
  • -
  • -
  • @@ -71,7 +70,6 @@ {/foreach}
{$vote->name|html} - + {if $admin} - {/if} @@ -108,7 +106,7 @@ {* Line to add a new vote *} - {if $active && $editingVoteId == 0 && !$expired} + {if $active && $editingVoteId === 0 && !$expired}
@@ -121,19 +119,19 @@
  • -
  • -
  • -
  • diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index 9262183..639513a 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -5,7 +5,7 @@

    {__('Poll results', 'Votes of the poll')}

    - + @@ -81,7 +81,7 @@ {* Edited line *} - {if $editingVoteId == $vote->id && !$expired} + {if $editingVoteId === $vote->uniqId && !$expired} {/foreach} - + {else} {* Voted line *} @@ -138,7 +138,7 @@ {/foreach} - + {/if} diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index 639513a..c081576 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -115,7 +115,7 @@ {/foreach} - + {else} {* Voted line *} @@ -190,7 +190,7 @@ {$i = $i+1} {/foreach} {/foreach} - + {/if} From 1f55167e2c10ade4e169880c18980fc55a5bef39 Mon Sep 17 00:00:00 2001 From: Antonin Date: Sun, 5 Apr 2015 15:41:19 +0200 Subject: [PATCH 07/18] Added new editable possibility at poll creation --- app/classes/Framadate/Editable.php | 25 +++++++++++++++++++++++++ app/classes/Framadate/Form.php | 5 ++++- app/inc/constants.php | 1 + create_poll.php | 18 +++++++----------- locale/de.json | 2 ++ locale/en.json | 2 ++ locale/es.json | 6 ++++-- locale/fr.json | 4 +++- tpl/create_poll.tpl | 12 ++++++++++-- 9 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 app/classes/Framadate/Editable.php diff --git a/app/classes/Framadate/Editable.php b/app/classes/Framadate/Editable.php new file mode 100644 index 0000000..df3c384 --- /dev/null +++ b/app/classes/Framadate/Editable.php @@ -0,0 +1,25 @@ +editable = true; + $this->editable = Editable::NOT_EDITABLE; $this->clearChoices(); } diff --git a/app/inc/constants.php b/app/inc/constants.php index fb5b618..cada2f8 100644 --- a/app/inc/constants.php +++ b/app/inc/constants.php @@ -25,6 +25,7 @@ const POLL_REGEX = '/^[a-zA-Z0-9]+$/'; const CHOICE_REGEX = '/^[012]$/'; const NAME_REGEX = '/^[áàâäãåçéèêëíìîïñóòôöõúùûüýÿæœa-z0-9_ -]+$/i'; const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/'; +const EDITABLE_CHOICE_REGEX = '/^[0-2]$/'; // CSRF (300s = 5min) const TOKEN_TIME = 300; diff --git a/create_poll.php b/create_poll.php index c9b12f4..567bc0f 100644 --- a/create_poll.php +++ b/create_poll.php @@ -4,20 +4,21 @@ * is not distributed with this file, you can obtain one at * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt * - * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ + * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Rapha�l DROZ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft) * * ============================= * - * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence + * Ce logiciel est r�gi par la licence CeCILL-B. Si une copie de cette licence * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt * - * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ + * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Rapha�l DROZ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) */ use Framadate\Form; +use Framadate\Editable; use Framadate\Utils; include_once __DIR__ . '/app/inc/init.php'; @@ -45,12 +46,12 @@ $title = filter_input(INPUT_POST, 'title', FILTER_SANITIZE_STRING); $name = filter_input(INPUT_POST, 'name', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => NAME_REGEX]]); $mail = filter_input(INPUT_POST, 'mail', FILTER_VALIDATE_EMAIL); $description = filter_input(INPUT_POST, 'description', FILTER_SANITIZE_STRING); -$editable = filter_input(INPUT_POST, 'editable', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); +$editable = filter_input(INPUT_POST, 'editable', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => EDITABLE_CHOICE_REGEX]]); $receiveNewVotes = filter_input(INPUT_POST, 'receiveNewVotes', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); $receiveNewComments = filter_input(INPUT_POST, 'receiveNewComments', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); -// On initialise également les autres variables +// On initialise �galement les autres variables $error_on_mail = false; $error_on_title = false; $error_on_name = false; @@ -62,7 +63,7 @@ if (!empty($_POST[GO_TO_STEP_2])) { $_SESSION['form']->admin_name = $name; $_SESSION['form']->admin_mail = $mail; $_SESSION['form']->description = $description; - $_SESSION['form']->editable = ($editable !== null); + $_SESSION['form']->editable = $editable; $_SESSION['form']->receiveNewVotes = ($receiveNewVotes !== null); $_SESSION['form']->receiveNewComments = ($receiveNewComments !== null); @@ -175,10 +176,6 @@ if (!empty($_POST[GO_TO_STEP_2])) { } // Checkbox checked ? -if ($_SESSION['form']->editable) { - $editable = 'checked'; -} - if ($_SESSION['form']->receiveNewVotes) { $receiveNewVotes = 'checked'; } @@ -187,7 +184,6 @@ if ($_SESSION['form']->receiveNewComments) { $receiveNewComments = 'checked'; } - $useRemoteUser = USE_REMOTE_USER && isset($_SERVER['REMOTE_USER']); $smarty->assign('title', $title); diff --git a/locale/de.json b/locale/de.json index 03f6540..9a99039 100644 --- a/locale/de.json +++ b/locale/de.json @@ -186,6 +186,8 @@ "You are in the poll creation section.": "Sie können hier Umfragen erstellen", "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.", diff --git a/locale/en.json b/locale/en.json index 5403eef..06d0297 100644 --- a/locale/en.json +++ b/locale/en.json @@ -187,6 +187,8 @@ "You are in the poll creation section.": "You are in the poll creation section.", "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.", diff --git a/locale/es.json b/locale/es.json index a11b5c7..55aa455 100644 --- a/locale/es.json +++ b/locale/es.json @@ -186,8 +186,10 @@ "You are in the poll creation section.": "Usted ha eligiendo de crear une nueva encuesta!", "Required fields cannot be left blank.": "Gracias por completar los campos con una *.", "Poll title": "ES_Titre du sondage", - "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.", + "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.", "Go to step 2": "ES_Aller à l'étape 2" }, diff --git a/locale/fr.json b/locale/fr.json index a962f1a..21261d1 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -186,7 +186,9 @@ "You are in the poll creation section.": "Vous avez choisi de créer un nouveau sondage.", "Required fields cannot be left blank.": "Merci de remplir les champs obligatoires, marqués d'une *.", "Poll title": "Titre du sondage", - "Voters can modify their vote themselves.": "Vous souhaitez que les sondés puissent modifier leur ligne eux-mêmes.", + "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.", "Go to step 2": "Aller à l'étape 2" diff --git a/tpl/create_poll.tpl b/tpl/create_poll.tpl index ec0e665..47156c6 100644 --- a/tpl/create_poll.tpl +++ b/tpl/create_poll.tpl @@ -90,9 +90,17 @@
    -
    +
    + +
    From a3f5763edd1422fe51eb5b210bebc0dfd940ebaa Mon Sep 17 00:00:00 2001 From: Antonin Date: Sun, 5 Apr 2015 17:44:29 +0200 Subject: [PATCH 08/18] New edition possibility is taken into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Also added Framadate\Message à link attribute - Added local anchor #edit with vote edition - For now, when the poll owner check the new edit option (ie: "Votes are editable solely by their owner"), users get their update link on vote creation --- adminstuds.php | 12 +++++++++--- app/classes/Framadate/FramaDB.php | 2 +- app/classes/Framadate/Message.php | 4 +++- app/classes/Framadate/Utils.php | 4 ++-- app/inc/smarty.php | 4 ++-- locale/de.json | 4 +++- locale/en.json | 4 +++- locale/es.json | 4 +++- locale/fr.json | 4 +++- studs.php | 8 +++++++- tpl/part/poll_info.tpl | 1 + tpl/part/vote_table_classic.tpl | 4 ++-- tpl/part/vote_table_date.tpl | 5 ++--- tpl/studs.tpl | 2 +- 14 files changed, 42 insertions(+), 20 deletions(-) diff --git a/adminstuds.php b/adminstuds.php index b7fe959..997788e 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -22,6 +22,7 @@ use Framadate\Services\InputService; use Framadate\Services\LogService; use Framadate\Message; use Framadate\Utils; +use Framadate\Editable; include_once __DIR__ . '/app/inc/init.php'; @@ -95,17 +96,22 @@ if (isset($_POST['update_poll_info'])) { switch ($rules) { case 0: $poll->active = false; - $poll->editable = false; + $poll->editable = Editable::NOT_EDITABLE; $updated = true; break; case 1: $poll->active = true; - $poll->editable = false; + $poll->editable = Editable::NOT_EDITABLE; $updated = true; break; case 2: $poll->active = true; - $poll->editable = true; + $poll->editable = Editable::EDITABLE_BY_ALL; + $updated = true; + break; + case 3: + $poll->active = true; + $poll->editable = Editable::EDITABLE_BY_OWN; $updated = true; break; } diff --git a/app/classes/Framadate/FramaDB.php b/app/classes/Framadate/FramaDB.php index ba1b250..8159b33 100644 --- a/app/classes/Framadate/FramaDB.php +++ b/app/classes/Framadate/FramaDB.php @@ -131,7 +131,7 @@ class FramaDB { $newVote->id = $this->pdo->lastInsertId(); $newVote->name = $name; $newVote->choices = $choices; - $newVote->token = $token; + $newVote->uniqId = $token; return $newVote; } diff --git a/app/classes/Framadate/Message.php b/app/classes/Framadate/Message.php index 9819e00..c7d7ede 100644 --- a/app/classes/Framadate/Message.php +++ b/app/classes/Framadate/Message.php @@ -22,10 +22,12 @@ class Message { var $type; var $message; + var $link; - function __construct($type, $message) { + function __construct($type, $message, $link=null) { $this->type = $type; $this->message = $message; + $this->link = $link; } } diff --git a/app/classes/Framadate/Utils.php b/app/classes/Framadate/Utils.php index 6a91a27..9c0ab32 100644 --- a/app/classes/Framadate/Utils.php +++ b/app/classes/Framadate/Utils.php @@ -110,7 +110,7 @@ class Utils { } else { $url = str_replace('/admin', '', self::get_server_name()) . $id; if ($vote_id != '') { - $url .= '/vote/'.$vote_id; + $url .= '/vote/'.$vote_id."#edit"; } } } else { @@ -119,7 +119,7 @@ class Utils { } else { $url = str_replace('/admin', '', self::get_server_name()) . 'studs.php?poll=' . $id; if ($vote_id != '') { - $url .= '&vote='.$vote_id; + $url .= '&vote='.$vote_id."#edit"; } } } diff --git a/app/inc/smarty.php b/app/inc/smarty.php index 87e8046..98ad34b 100644 --- a/app/inc/smarty.php +++ b/app/inc/smarty.php @@ -47,8 +47,8 @@ if ($_SERVER['FRAMADATE_DEVMODE']) { function smarty_function_poll_url($params, Smarty_Internal_Template $template) { $poll_id = filter_var($params['id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); - $admin = $params['admin']?true:false; - $vote_unique_id = filter_var($params['vote_id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + $admin = (isset($params['admin']) && $params['admin']) ? true : false; + $vote_unique_id = isset($params['vote_id']) ? filter_var($params['vote_id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]) : ''; // If filter_var fails (i.e.: hack tentative), it will return false. At least no leak is possible from this. diff --git a/locale/de.json b/locale/de.json index 9a99039..a28e227 100644 --- a/locale/de.json +++ b/locale/de.json @@ -111,6 +111,7 @@ "Votes and comments are locked": "Abstimmungen und Kommentare sind gesperrt", "Votes and comments are open": "Abstimmungen und Kommentare sind möglich", "Votes are editable": "Die Abstimmungen können geändert werden", + "Votes are editable solely by their owner.": "DE_Les votes sont modifiables uniquement par leur créateur", "Save the new rules": "Neue Regeln speichern", "Cancel the rules edit": "Neue Regeln nicht speichern", "The name is invalid.": "Der Name ist ungültig." @@ -144,7 +145,8 @@ "If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.": "Wenn Sie bei dieser Umfrage abstimmen möchten, müssen Sie ihren Namen angeben. Wählen Sie die Optionen, die für Sie am besten passen und bestätigen Sie diese über den Plus-Button am Ende der Zeile.", "POLL_LOCKED_WARNING": "Die Administration gesperrt diese Umfrage. Bewertungen und Kommentare werden eingefroren, es ist nicht mehr möglich, teilzunehmen", "The poll is expired, it will be deleted soon.": "Die Umfrage ist abgelaufen, es wird bald gelöscht werden.", - "Deletion date:": "Löschdatum:" + "Deletion date:": "Löschdatum:", + "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "DE_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "Als Administrator der Umfrage, können Sie alle Zeilen der Umfrage über diesen Button ändern", diff --git a/locale/en.json b/locale/en.json index 06d0297..b69babf 100644 --- a/locale/en.json +++ b/locale/en.json @@ -112,6 +112,7 @@ "Votes and comments are locked": "Votes and comments are locked", "Votes and comments are open": "Votes and comments are open", "Votes are editable": "Votes are editable", + "Votes are editable solely by their owner.": "Votes are editable solely by their owner", "Save the new rules": "Save the new rules", "Cancel the rules edit": "Cancel the rules edit", "The name is invalid.": "The name is invalid." @@ -145,7 +146,8 @@ "If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.": "If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.", "POLL_LOCKED_WARNING": "The administration locked this poll. Votes and comments are frozen, it is no longer possible to participate", "The poll is expired, it will be deleted soon.": "The poll is expired, it will be deleted soon.", - "Deletion date:": "Deletion date:" + "Deletion date:": "Deletion date:", + "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "As poll administrator, you can change all the lines of this poll with this button", diff --git a/locale/es.json b/locale/es.json index 55aa455..ad35a9a 100644 --- a/locale/es.json +++ b/locale/es.json @@ -111,6 +111,7 @@ "Votes and comments are locked": "ES_Les votes et commentaires sont verrouillés", "Votes and comments are open": "ES_Les votes et commentaires sont ouverts", "Votes are editable": "ES_Les votes sont modifiables", + "Votes are editable solely by their owner.": "ES_Les votes sont modifiables uniquement par leur créateur", "Save the new rules": "ES_Enregistrer les nouvelles permissions", "Cancel the rules edit": "ES_Annuler le changement de permissions", "The name is invalid.": "ES_Le nom n'est pas valide." @@ -144,7 +145,8 @@ "If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.": "Para participar a esta encuesta, introduzca su nombre, elige todas las valores que son apriopriadas y validar su seleccion con el botón verde a la fin de línea.", "POLL_LOCKED_WARNING": "ES_L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer", "The poll is expired, it will be deleted soon.": "ES_Le sondage a expiré, il sera bientôt supprimé.", - "Deletion date:": "ES_Date de suppression :" + "Deletion date:": "ES_Date de suppression :", + "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "ES_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "En calidad de administrador, Usted puede cambiar todas la líneas de este encuesta con este botón", diff --git a/locale/fr.json b/locale/fr.json index 21261d1..241836d 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -111,6 +111,7 @@ "Votes and comments are locked": "Les votes et commentaires sont verrouillés", "Votes and comments are open": "Les votes et commentaires sont ouverts", "Votes are editable": "Les votes sont modifiables", + "Votes are editable solely by their owner.": "Les votes sont modifiables uniquement par leur créateur", "Save the new rules": "Enregistrer les nouvelles permissions", "Cancel the rules edit": "Annuler le changement de permissions", "The name is invalid.": "Le nom n'est pas valide." @@ -144,7 +145,8 @@ "If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.": "Pour participer à ce sondage, veuillez entrer votre nom, choisir toutes les valeurs qui vous conviennent et valider votre choix avec le bouton en bout de ligne.", "POLL_LOCKED_WARNING": "L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer", "The poll is expired, it will be deleted soon.": "Le sondage a expiré, il sera bientôt supprimé.", - "Deletion date:": "Date de suppression :" + "Deletion date:": "Date de suppression :", + "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton", diff --git a/studs.php b/studs.php index c965917..142a371 100644 --- a/studs.php +++ b/studs.php @@ -22,6 +22,7 @@ use Framadate\Services\InputService; use Framadate\Services\MailService; use Framadate\Message; use Framadate\Utils; +use Framadate\Editable; include_once __DIR__ . '/app/inc/init.php'; @@ -155,7 +156,12 @@ if (!empty($_POST['save'])) { // Save edition of an old vote // Add vote $result = $pollService->addVote($poll_id, $name, $choices); if ($result) { - $message = new Message('success', _('Update vote successfully.')); + if ($poll->editable == Editable::EDITABLE_BY_OWN) { + $urlEditVote = Utils::getUrlSondage($poll_id, false, $result->uniqId); + $message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : "), $urlEditVote); + } else { + $message = new Message('success', _('Update vote successfully.')); + } sendUpdateNotification($poll, $mailService, $name, ADD_VOTE); } else { $message = new Message('danger', _('Update vote failed.')); diff --git a/tpl/part/poll_info.tpl b/tpl/part/poll_info.tpl index b39d1c9..645f9b1 100644 --- a/tpl/part/poll_info.tpl +++ b/tpl/part/poll_info.tpl @@ -144,6 +144,7 @@ + diff --git a/tpl/part/vote_table_classic.tpl b/tpl/part/vote_table_classic.tpl index 786ab3d..3183a11 100644 --- a/tpl/part/vote_table_classic.tpl +++ b/tpl/part/vote_table_classic.tpl @@ -37,7 +37,7 @@ {if $editingVoteId === $vote->uniqId}
    {/foreach} - {else} + {elseif !$hidden} {* Voted line *} @@ -142,55 +142,58 @@ {/if} - {* Line displaying best moments *} - {$count_bests = 0} - {$max = max($best_choices)} - {if $max > 0} - - - {foreach $best_choices as $best_choice} - {if $max == $best_choice} - {$count_bests = $count_bests +1} - - {elseif $best_choice > 0} - - {else} - - {/if} - {/foreach} - + {if !$hidden} + {* Line displaying best moments *} + {$count_bests = 0} + {$max = max($best_choices)} + {if $max > 0} + + + {foreach $best_choices as $best_choice} + {if $max == $best_choice} + {$count_bests = $count_bests +1} + + {elseif $best_choice > 0} + + {else} + + {/if} + {/foreach} + + {/if} {/if}
    {__('Poll results', 'Votes of the poll')} {$poll->title|html}
    @@ -136,9 +136,9 @@ {if $active && $poll->editable && !$expired}
    - + {if $admin}
    From 6d31f180e333aab4b3f41c205372b1cfd70a97a3 Mon Sep 17 00:00:00 2001 From: Antonin Date: Thu, 2 Apr 2015 17:25:01 +0200 Subject: [PATCH 06/18] Javascript protection on invalid name : can now use form submission. --- js/app/studs.js | 8 ++++---- tpl/part/vote_table_classic.tpl | 4 ++-- tpl/part/vote_table_date.tpl | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/js/app/studs.js b/js/app/studs.js index c19817a..0266c63 100644 --- a/js/app/studs.js +++ b/js/app/studs.js @@ -3,22 +3,22 @@ * is not distributed with this file, you can obtain one at * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt * - * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ + * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft) * * ============================= * - * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence + * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt * - * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ + * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) */ $(document).ready(function () { - $(".check-name").click(function (event) { + $("#poll_form").submit(function (event) { var name = $("#name").val(); var regexContent = $("#parameter_name_regex").text().split("/"); var regex = new RegExp(regexContent[1], regexContent[2]); diff --git a/tpl/part/vote_table_classic.tpl b/tpl/part/vote_table_classic.tpl index f94e169..786ab3d 100644 --- a/tpl/part/vote_table_classic.tpl +++ b/tpl/part/vote_table_classic.tpl @@ -68,7 +68,7 @@
    -
    +
    @@ -86,7 +86,7 @@ {/foreach} - {if $active && $poll->editable && !$expired} + {if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
    {__('Generic', 'Edit')} diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index c081576..49f19a5 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -82,9 +82,8 @@ {* Edited line *} {if $editingVoteId === $vote->uniqId && !$expired} - -
    +
    @@ -134,7 +133,7 @@ {/foreach} - {if $active && $poll->editable && !$expired} + {if $active && !$expired && ($poll->editable == constant('Framadate\Editable::EDITABLE_BY_ALL') or $admin)}
    {__('Generic', 'Edit')} diff --git a/tpl/studs.tpl b/tpl/studs.tpl index 10d1c04..e553fd4 100644 --- a/tpl/studs.tpl +++ b/tpl/studs.tpl @@ -9,7 +9,7 @@ From 0c2ba20bfacc5286e00dfc24d045985aebcec8d1 Mon Sep 17 00:00:00 2001 From: Antonin Date: Sun, 5 Apr 2015 18:36:43 +0200 Subject: [PATCH 09/18] Added option of poll with hidden results. --- admin/migration.php | 4 +- app/classes/Framadate/Form.php | 6 ++ .../AddColumn_hidden_In_poll_For_0_9.php | 77 +++++++++++++++++++ create_poll.php | 14 +--- js/app/create_poll.js | 54 +++++++++++++ locale/de.json | 2 + locale/en.json | 4 +- locale/es.json | 4 +- locale/fr.json | 4 +- tpl/create_poll.tpl | 52 ++++++------- 10 files changed, 178 insertions(+), 43 deletions(-) create mode 100644 app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php create mode 100644 js/app/create_poll.js diff --git a/admin/migration.php b/admin/migration.php index f60d9ce..25bc733 100644 --- a/admin/migration.php +++ b/admin/migration.php @@ -21,6 +21,7 @@ use Framadate\Migration\From_0_0_to_0_8_Migration; use Framadate\Migration\From_0_8_to_0_9_Migration; use Framadate\Migration\AddColumn_receiveNewComments_For_0_9; use Framadate\Migration\AddColumn_uniqId_In_vote_For_0_9; +use Framadate\Migration\AddColumn_hidden_In_poll_For_0_9; use Framadate\Migration\Migration; use Framadate\Utils; @@ -33,7 +34,8 @@ $migrations = [ new From_0_0_to_0_8_Migration(), new From_0_8_to_0_9_Migration(), new AddColumn_receiveNewComments_For_0_9(), - new AddColumn_uniqId_In_vote_For_0_9() + new AddColumn_uniqId_In_vote_For_0_9(), + new AddColumn_hidden_In_poll_For_0_9(), ]; // --------------------------------------- diff --git a/app/classes/Framadate/Form.php b/app/classes/Framadate/Form.php index 2570fc4..00f8c4f 100644 --- a/app/classes/Framadate/Form.php +++ b/app/classes/Framadate/Form.php @@ -47,6 +47,12 @@ class Form */ public $receiveNewComments; + /** + * If true, only the poll maker can see the poll's results + * @var boolean + */ + public $hidden; + /** * List of available choices */ diff --git a/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php b/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php new file mode 100644 index 0000000..c046752 --- /dev/null +++ b/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php @@ -0,0 +1,77 @@ +query('SHOW TABLES'); + $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN); + + // Check if tables of v0.9 are presents + $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables); + return count($diff) === 0; + } + + /** + * This methode is called only one time in the migration page. + * + * @param \PDO $pdo The connection to database + * @return bool true is the execution succeeded + */ + function execute(\PDO $pdo) { + $this->alterPollTable($pdo); + + return true; + } + + private function alterPollTable(\PDO $pdo) { + $pdo->exec(' + ALTER TABLE `' . Utils::table('poll') . '` + ADD `hidden` TINYINT( 1 ) NOT NULL DEFAULT "0"'); + } + +} diff --git a/create_poll.php b/create_poll.php index 567bc0f..664182d 100644 --- a/create_poll.php +++ b/create_poll.php @@ -49,6 +49,7 @@ $description = filter_input(INPUT_POST, 'description', FILTER_SANITIZE_STRING); $editable = filter_input(INPUT_POST, 'editable', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => EDITABLE_CHOICE_REGEX]]); $receiveNewVotes = filter_input(INPUT_POST, 'receiveNewVotes', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); $receiveNewComments = filter_input(INPUT_POST, 'receiveNewComments', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); +$hidden = filter_input(INPUT_POST, 'hidden', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]); // On initialise �galement les autres variables @@ -57,7 +58,7 @@ $error_on_title = false; $error_on_name = false; $error_on_description = false; -// + if (!empty($_POST[GO_TO_STEP_2])) { $_SESSION['form']->title = $title; $_SESSION['form']->admin_name = $name; @@ -66,6 +67,7 @@ if (!empty($_POST[GO_TO_STEP_2])) { $_SESSION['form']->editable = $editable; $_SESSION['form']->receiveNewVotes = ($receiveNewVotes !== null); $_SESSION['form']->receiveNewComments = ($receiveNewComments !== null); + $_SESSION['form']->hidden = ($hidden !== null); if ($config['use_smtp'] == true) { if (empty($mail)) { @@ -175,15 +177,6 @@ if (!empty($_POST[GO_TO_STEP_2])) { } } -// Checkbox checked ? -if ($_SESSION['form']->receiveNewVotes) { - $receiveNewVotes = 'checked'; -} - -if ($_SESSION['form']->receiveNewComments) { - $receiveNewComments = 'checked'; -} - $useRemoteUser = USE_REMOTE_USER && isset($_SERVER['REMOTE_USER']); $smarty->assign('title', $title); @@ -200,6 +193,7 @@ $smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $_SESSION['form']- $smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $_SESSION['form']->editable)); $smarty->assign('poll_receiveNewVotes', Utils::fromPostOrDefault('receiveNewVotes', $_SESSION['form']->receiveNewVotes)); $smarty->assign('poll_receiveNewComments', Utils::fromPostOrDefault('receiveNewComments', $_SESSION['form']->receiveNewComments)); +$smarty->assign('poll_hidden', Utils::fromPostOrDefault('hidden', $_SESSION['form']->hidden)); $smarty->assign('form', $_SESSION['form']); $smarty->display('create_poll.tpl'); diff --git a/js/app/create_poll.js b/js/app/create_poll.js new file mode 100644 index 0000000..66521dc --- /dev/null +++ b/js/app/create_poll.js @@ -0,0 +1,54 @@ +/** + * This software is governed by the CeCILL-B license. If a copy of this license + * is not distributed with this file, you can obtain one at + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt + * + * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ + * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft) + * + * ============================= + * + * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence + * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur + * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt + * + * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ + * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) + */ + +$(document).ready(function () { + + $("#formulaire").submit(function (event) { + var isHidden = $("#hidden").prop('checked'); + var isOptionAllUserCanModifyEverything = $("#editableByAll").is(":checked"); + + if (isHidden && isOptionAllUserCanModifyEverything) { + event.preventDefault(); + $("#hiddenWithBadEditionModeError").removeClass("hidden"); + } else { + $("#hiddenWithBadEditionModeError").addClass("hidden"); + } + }); + + // Check cookies are enabled too + var cookieEnabled = function () { + var cookieEnabled = navigator.cookieEnabled; + + // if not IE4+ nor NS6+ + if (!cookieEnabled && typeof navigator.cookieEnabled === "undefined") { + document.cookie = "testcookie"; + cookieEnabled = document.cookie.indexOf("testcookie") != -1; + } + + return cookieEnabled; + }; + + if (cookieEnabled()) { + // Show the form block + document.getElementById("form-block").setAttribute("style", ""); + } else { + // Show the warning about cookies + document.getElementById("cookie-warning").setAttribute("style", ""); + } + +}); \ No newline at end of file diff --git a/locale/de.json b/locale/de.json index a28e227..185e54e 100644 --- a/locale/de.json +++ b/locale/de.json @@ -193,6 +193,7 @@ "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": { @@ -302,5 +303,6 @@ "Failed to save poll": "Fehlgeschlagen Umfrage sparen", "Update vote failed": "Update vote failed", "Adding vote failed": "Adding vote failed" + "You can't create a poll with hidden results with the following edition option : ": "DE_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : " } } \ No newline at end of file diff --git a/locale/en.json b/locale/en.json index b69babf..6408140 100644 --- a/locale/en.json +++ b/locale/en.json @@ -194,6 +194,7 @@ "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": { @@ -302,6 +303,7 @@ "Framadate is not properly installed, please check the \"INSTALL\" to setup the database before continuing.": "Framadate is not properly installed, please check the 'INSTALL' to setup the database before continuing.", "Failed to save poll": "Failed to save poll", "Update vote failed": "Update vote failed", - "Adding vote failed": "Adding vote failed" + "Adding vote failed": "Adding vote 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 : " } } \ No newline at end of file diff --git a/locale/es.json b/locale/es.json index ad35a9a..5005976 100644 --- a/locale/es.json +++ b/locale/es.json @@ -193,6 +193,7 @@ "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": { @@ -301,6 +302,7 @@ "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", "Update vote failed": "ES_Mise à jour du vote échoué", - "Adding vote failed": "ES_Ajout d'un vote échoué" + "Adding vote failed": "ES_Ajout d'un vote é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 : " } } \ No newline at end of file diff --git a/locale/fr.json b/locale/fr.json index 241836d..1fa44d5 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -193,6 +193,7 @@ "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": { @@ -301,6 +302,7 @@ "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", "Update vote failed": "Mise à jour du vote échoué", - "Adding vote failed": "Ajout d'un vote échoué" + "Adding vote failed": "Ajout d'un vote é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 : " } } diff --git a/tpl/create_poll.tpl b/tpl/create_poll.tpl index 47156c6..ec01d90 100644 --- a/tpl/create_poll.tpl +++ b/tpl/create_poll.tpl @@ -1,5 +1,9 @@ {extends file='page.tpl'} +{block name="header"} + +{/block} + {block name=main} {$vote->name|html}
    {__('Poll results', 'Addition')}{$best_choice|html}{$best_choice|html}
    {__('Poll results', 'Addition')}{$best_choice|html}{$best_choice|html}
    -{* Best votes listing *} - -{$max = max($best_choices)} -{if $max > 0} -
    - {if $count_bests == 1} -

    {__('Poll results', 'Best choice')}

    -
    -

    {__('Poll results', 'The best choice at this time is:')}

    - {elseif $count_bests > 1} -

    {__('Poll results', 'Best choices')}

    +{if !$hidden} + {* Best votes listing *} + {$max = max($best_choices)} + {if $max > 0} +
    + {if $count_bests == 1} +

    {__('Poll results', 'Best choice')}

    -

    {__('Poll results', 'The bests choices at this time are:')}

    - {/if} +

    {__('Poll results', 'The best choice at this time is:')}

    + {elseif $count_bests > 1} +

    {__('Poll results', 'Best choices')}

    +
    +

    {__('Poll results', 'The bests choices at this time are:')}

    + {/if} - {$i = 0} -
      - {foreach $slots as $slot} - {if $best_choices[$i] == $max} -
    • {$slot->title|html|markdown:true}
    • - {/if} - {$i = $i+1} - {/foreach} -
    -

    {__('Generic', 'with')} {$max|html} {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.

    + {$i = 0} +
      + {foreach $slots as $slot} + {if $best_choices[$i] == $max} +
    • {$slot->title|html|markdown:true}
    • + {/if} + {$i = $i+1} + {/foreach} +
    +

    {__('Generic', 'with')} {$max|html} {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.

    +
    -
    + {/if} {/if} \ No newline at end of file diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index 49f19a5..c104d41 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -2,7 +2,7 @@ {$best_choices = [0]} {/if} -

    {__('Poll results', 'Votes of the poll')}

    +

    {__('Poll results', 'Votes of the poll')} {if $hidden}({__('PollInfo', 'Results are hidden.')}){/if}

    @@ -115,7 +115,7 @@
{__('Poll results', 'Addition')}{$best_moment|html}{$best_moment|html}
{__('Poll results', 'Addition')}{$best_moment|html}{$best_moment|html}
-{* Best votes listing *} - -{$max = max($best_choices)} -{if $max > 0} -
- {if $count_bests == 1} -

{__('Poll results', 'Best choice')}

-
-

{__('Poll results', 'The best choice at this time is:')}

- {elseif $count_bests > 1} -

{__('Poll results', 'Best choices')}

+{if !$hidden} + {* Best votes listing *} + {$max = max($best_choices)} + {if $max > 0} +
+ {if $count_bests == 1} +

{__('Poll results', 'Best choice')}

-

{__('Poll results', 'The bests choices at this time are:')}

- {/if} +

{__('Poll results', 'The best choice at this time is:')}

+ {elseif $count_bests > 1} +

{__('Poll results', 'Best choices')}

+
+

{__('Poll results', 'The bests choices at this time are:')}

+ {/if} - {$i = 0} -
    - {foreach $slots as $slot} - {foreach $slot->moments as $moment} - {if $best_choices[$i] == $max} -
  • {$slot->day|date_format:$date_format.txt_full|html} - {$moment|html}
  • - {/if} - {$i = $i+1} + {$i = 0} +
      + {foreach $slots as $slot} + {foreach $slot->moments as $moment} + {if $best_choices[$i] == $max} +
    • {$slot->day|date_format:$date_format.txt_full|html} - {$moment|html}
    • + {/if} + {$i = $i+1} + {/foreach} {/foreach} - {/foreach} -
    -

    {__('Generic', 'with')} {$max|html} {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.

    +
+

{__('Generic', 'with')} {$max|html} {if $max==1}{__('Generic', 'vote')}{else}{__('Generic', 'votes')}{/if}.

+
-
+ {/if} {/if} \ No newline at end of file From 1e39eae05633384b1760525098bcc02c61aa4d20 Mon Sep 17 00:00:00 2001 From: Antonin Date: Mon, 6 Apr 2015 12:54:18 +0200 Subject: [PATCH 11/18] Changed the file header to framadate license --- app/classes/Framadate/Editable.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/app/classes/Framadate/Editable.php b/app/classes/Framadate/Editable.php index df3c384..142265d 100644 --- a/app/classes/Framadate/Editable.php +++ b/app/classes/Framadate/Editable.php @@ -1,9 +1,20 @@ Date: Mon, 6 Apr 2015 14:06:47 +0200 Subject: [PATCH 12/18] Changed defaut edition option --- app/classes/Framadate/Form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/classes/Framadate/Form.php b/app/classes/Framadate/Form.php index 00f8c4f..ce802ba 100644 --- a/app/classes/Framadate/Form.php +++ b/app/classes/Framadate/Form.php @@ -59,7 +59,7 @@ class Form private $choices; public function __construct(){ - $this->editable = Editable::NOT_EDITABLE; + $this->editable = Editable::EDITABLE_BY_ALL; $this->clearChoices(); } From 213980e80788e6a99957df5b0c04530566752128 Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:09:18 +0200 Subject: [PATCH 13/18] Remove POST['poll'] access --- adminstuds.php | 8 ++------ studs.php | 12 +++++------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/adminstuds.php b/adminstuds.php index 07ee442..92262c8 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -46,12 +46,8 @@ $inputService = new InputService(); /* PAGE */ /* ---- */ -if (!empty($_POST['poll']) || !empty($_GET['poll'])) { - if (!empty($_POST['poll'])) - $inputType = INPUT_POST; - else - $inputType = INPUT_GET; - $admin_poll_id = filter_input($inputType, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); +if (!empty($_GET['poll'])) { + $admin_poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); if (strlen($admin_poll_id) === 24) { $poll_id = substr($admin_poll_id, 0, 16); $poll = $pollService->findById($poll_id); diff --git a/studs.php b/studs.php index ad5e323..bd7ec29 100644 --- a/studs.php +++ b/studs.php @@ -92,13 +92,11 @@ function sendUpdateNotification($poll, $mailService, $name, $type) { /* PAGE */ /* ---- */ -if (!empty($_POST['poll']) || !empty($_GET['poll'])) { - if (!empty($_POST['poll'])) - $inputType = INPUT_POST; - else - $inputType = INPUT_GET; - $poll_id = filter_input($inputType, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); - $poll = $pollService->findById($poll_id); +if (!empty($_GET['poll'])) { + $poll_id = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + if (strlen($poll_id) === 16) { + $poll = $pollService->findById($poll_id); + } } if (!$poll) { From af668d2428ad20e789cdb119408c2b6d9fa4a1d9 Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:28:04 +0200 Subject: [PATCH 14/18] Correcting 'Undefined index' notice on hidden --- adminstuds.php | 1 + 1 file changed, 1 insertion(+) diff --git a/adminstuds.php b/adminstuds.php index 92262c8..d4da24b 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -388,6 +388,7 @@ $smarty->assign('comments', $comments); $smarty->assign('editingVoteId', $editingVoteId); $smarty->assign('message', $message); $smarty->assign('admin', true); +$smarty->assign('hidden', $poll->hidden); $smarty->assign('parameter_name_regex', NAME_REGEX); $smarty->display('studs.tpl'); \ No newline at end of file From 1058d3653be04cef5d531e80d271f5392e77831b Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:29:15 +0200 Subject: [PATCH 15/18] Correcting 'Undefined index' notice on DevMode var --- app/inc/smarty.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/inc/smarty.php b/app/inc/smarty.php index 98ad34b..63cea1d 100644 --- a/app/inc/smarty.php +++ b/app/inc/smarty.php @@ -35,7 +35,7 @@ $smarty->assign('langs', $ALLOWED_LANGUAGES); $smarty->assign('date_format', $date_format); // Dev Mode -if ($_SERVER['FRAMADATE_DEVMODE']) { +if (isset($_SERVER['FRAMADATE_DEVMODE']) && $_SERVER['FRAMADATE_DEVMODE']) { $smarty->force_compile = true; $smarty->compile_check = true; From bd00cf191532d9af728a7aebd2c129595e426c13 Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:36:29 +0200 Subject: [PATCH 16/18] From double quote to simple quote --- .../Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php | 2 +- .../Migration/AddColumn_receiveNewComments_For_0_9.php | 2 +- .../Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php | 2 +- app/classes/Framadate/Migration/From_0_0_to_0_8_Migration.php | 2 +- app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php b/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php index c046752..dd335f9 100644 --- a/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php +++ b/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php @@ -37,7 +37,7 @@ class AddColumn_hidden_In_poll_For_0_9 implements Migration { * @return string The description of the migration class */ function description() { - return "Add column \"hidden\" in table \"vote\" for version 0.9"; + return 'Add column "hidden" in table "vote" for version 0.9'; } /** diff --git a/app/classes/Framadate/Migration/AddColumn_receiveNewComments_For_0_9.php b/app/classes/Framadate/Migration/AddColumn_receiveNewComments_For_0_9.php index 9f698f9..865502a 100644 --- a/app/classes/Framadate/Migration/AddColumn_receiveNewComments_For_0_9.php +++ b/app/classes/Framadate/Migration/AddColumn_receiveNewComments_For_0_9.php @@ -37,7 +37,7 @@ class AddColumn_receiveNewComments_For_0_9 implements Migration { * @return string The description of the migration class */ function description() { - return "Add column \"receiveNewComments\" for version 0.9"; + return 'Add column "receiveNewComments" for version 0.9'; } /** diff --git a/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php b/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php index 9f50e4a..440d2de 100644 --- a/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php +++ b/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php @@ -37,7 +37,7 @@ class AddColumn_uniqId_In_vote_For_0_9 implements Migration { * @return string The description of the migration class */ function description() { - return "Add column \"uniqId\" in table \"vote\" for version 0.9"; + return 'Add column "uniqId" in table "vote" for version 0.9'; } /** diff --git a/app/classes/Framadate/Migration/From_0_0_to_0_8_Migration.php b/app/classes/Framadate/Migration/From_0_0_to_0_8_Migration.php index 4e0c0e8..ac985f5 100644 --- a/app/classes/Framadate/Migration/From_0_0_to_0_8_Migration.php +++ b/app/classes/Framadate/Migration/From_0_0_to_0_8_Migration.php @@ -37,7 +37,7 @@ class From_0_0_to_0_8_Migration implements Migration { * @return string The description of the migration class */ function description() { - return "First installation of the Framadate application (v0.8)"; + return 'First installation of the Framadate application (v0.8)'; } /** diff --git a/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php b/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php index 2920bd3..bed4fe8 100644 --- a/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php +++ b/app/classes/Framadate/Migration/From_0_8_to_0_9_Migration.php @@ -37,7 +37,7 @@ class From_0_8_to_0_9_Migration implements Migration { * @return string The description of the migration class */ function description() { - return "From 0.8 to 0.9"; + return 'From 0.8 to 0.9'; } /** From fbf448c415729f1e41681daf9baeb61b872b0ba2 Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:46:30 +0200 Subject: [PATCH 17/18] No space before ':' in english... --- locale/de.json | 4 ++-- locale/en.json | 4 ++-- locale/es.json | 4 ++-- locale/fr.json | 4 ++-- studs.php | 2 +- tpl/create_poll.tpl | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/locale/de.json b/locale/de.json index 09c148a..5a3512f 100644 --- a/locale/de.json +++ b/locale/de.json @@ -148,7 +148,7 @@ "POLL_LOCKED_WARNING": "Die Administration gesperrt diese Umfrage. Bewertungen und Kommentare werden eingefroren, es ist nicht mehr möglich, teilzunehmen", "The poll is expired, it will be deleted soon.": "Die Umfrage ist abgelaufen, es wird bald gelöscht werden.", "Deletion date:": "Löschdatum:", - "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "DE_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " + "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "DE_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "Als Administrator der Umfrage, können Sie alle Zeilen der Umfrage über diesen Button ändern", @@ -305,6 +305,6 @@ "Failed to save poll": "Fehlgeschlagen Umfrage sparen", "Update vote failed": "Update vote failed", "Adding vote failed": "Adding vote failed", - "You can't create a poll with hidden results with the following edition option : ": "DE_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:": "DE_Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : " } } \ No newline at end of file diff --git a/locale/en.json b/locale/en.json index 3096931..5e03ef4 100644 --- a/locale/en.json +++ b/locale/en.json @@ -149,7 +149,7 @@ "POLL_LOCKED_WARNING": "The administration locked this poll. Votes and comments are frozen, it is no longer possible to participate", "The poll is expired, it will be deleted soon.": "The poll is expired, it will be deleted soon.", "Deletion date:": "Deletion date:", - "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : " + "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote." }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "As poll administrator, you can change all the lines of this poll with this button", @@ -306,6 +306,6 @@ "Failed to save poll": "Failed to save poll", "Update vote failed": "Update vote failed", "Adding vote failed": "Adding vote 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: " } } \ No newline at end of file diff --git a/locale/es.json b/locale/es.json index 13604ea..601c291 100644 --- a/locale/es.json +++ b/locale/es.json @@ -148,7 +148,7 @@ "POLL_LOCKED_WARNING": "ES_L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer", "The poll is expired, it will be deleted soon.": "ES_Le sondage a expiré, il sera bientôt supprimé.", "Deletion date:": "ES_Date de suppression :", - "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "ES_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " + "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "ES_Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "En calidad de administrador, Usted puede cambiar todas la líneas de este encuesta con este botón", @@ -305,6 +305,6 @@ "Failed to save poll": "ES_Echèc de la sauvegarde du sondage", "Update vote failed": "ES_Mise à jour du vote échoué", "Adding vote failed": "ES_Ajout d'un vote é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 : " } } \ No newline at end of file diff --git a/locale/fr.json b/locale/fr.json index 49d923c..31bb497 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -148,7 +148,7 @@ "POLL_LOCKED_WARNING": "L'administrateur a verrouillé ce sondage. Les votes et commentaires sont gelés, il n'est plus possible de participer", "The poll is expired, it will be deleted soon.": "Le sondage a expiré, il sera bientôt supprimé.", "Deletion date:": "Date de suppression :", - "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : ": "Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " + "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:": "Votre vote a bien été pris en compte, mais faites attention : ce sondage n'autorise l'édition de votre vote qu'avec le lien personnalisé suivant ; conservez le précieusement ! " }, "adminstuds": { "As poll administrator, you can change all the lines of this poll with this button": "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton", @@ -305,6 +305,6 @@ "Failed to save poll": "Echèc de la sauvegarde du sondage", "Update vote failed": "Mise à jour du vote échoué", "Adding vote failed": "Ajout d'un vote é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 : " } } diff --git a/studs.php b/studs.php index bd7ec29..ba8423e 100644 --- a/studs.php +++ b/studs.php @@ -156,7 +156,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote if ($result) { if ($poll->editable == Editable::EDITABLE_BY_OWN) { $urlEditVote = Utils::getUrlSondage($poll_id, false, $result->uniqId); - $message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful : regarding this poll options, you need to keep this personal link to edit your own vote : "), $urlEditVote); + $message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:"), $urlEditVote); } else { $message = new Message('success', _('Update vote successfully.')); } diff --git a/tpl/create_poll.tpl b/tpl/create_poll.tpl index ec01d90..7d49a76 100644 --- a/tpl/create_poll.tpl +++ b/tpl/create_poll.tpl @@ -146,7 +146,7 @@
From 84e3a93645c4769c7d3e0d218853478231c2d22c Mon Sep 17 00:00:00 2001 From: Antonin Date: Tue, 7 Apr 2015 17:58:45 +0200 Subject: [PATCH 18/18] Add edit link with vote update --- studs.php | 8 +++++++- tpl/part/vote_table_classic.tpl | 1 + tpl/part/vote_table_date.tpl | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/studs.php b/studs.php index ba8423e..0d360d2 100644 --- a/studs.php +++ b/studs.php @@ -133,7 +133,13 @@ if (!empty($_POST['save'])) { // Save edition of an old vote // Update vote $result = $pollService->updateVote($poll_id, $editedVote, $name, $choices); if ($result) { - $message = new Message('success', _('Update vote successfully.')); + if ($poll->editable == Editable::EDITABLE_BY_OWN) { + $editedVoteUniqId = filter_input(INPUT_POST, 'edited_vote', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); + $urlEditVote = Utils::getUrlSondage($poll_id, false, $editedVoteUniqId); + $message = new Message('success', __('studs', "Your vote has been registered successfully, but be careful: regarding this poll options, you need to keep this personal link to edit your own vote:"), $urlEditVote); + } else { + $message = new Message('success', _('Update vote successfully.')); + } sendUpdateNotification($poll, $mailService, $name, UPDATE_VOTE); } else { $message = new Message('danger', _('Update vote failed.')); diff --git a/tpl/part/vote_table_classic.tpl b/tpl/part/vote_table_classic.tpl index 8e2973a..5ec4db5 100644 --- a/tpl/part/vote_table_classic.tpl +++ b/tpl/part/vote_table_classic.tpl @@ -39,6 +39,7 @@
+
diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index c104d41..f8bc22e 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -85,6 +85,7 @@
+