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
This commit is contained in:
Antonin 2015-04-02 16:52:46 +02:00
parent 86a89abf42
commit 4c137748b4
15 changed files with 84 additions and 48 deletions

View File

@ -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]]);
}
// -------------------------------

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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) {

13
htaccess.txt Normal file
View File

@ -0,0 +1,13 @@
######################
# .htaccess example. #
######################
<IfModule mod_rewrite.c>
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
</IfModule>

View File

@ -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]]);
}
// -------------------------------

View File

@ -1,7 +1,7 @@
{extends file='page.tpl'}
{block name=main}
<form action="{$admin_poll_id|poll_url:true}" method="POST">
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
<div class="alert alert-info text-center">
<h2>{__('adminstuds', 'Column\'s adding')}</h2>

View File

@ -91,11 +91,11 @@
{/if}
<td>{$poll->votes|html}</td>
<td>{$poll->id|html}</td>
<td><a href="{$poll->id|poll_url|html}" class="btn btn-link"
<td><a href="{poll_url id=$poll->id}" class="btn btn-link"
title="{__('Admin', 'See the poll')}"><span
class="glyphicon glyphicon-eye-open"></span><span
class="sr-only">{__('Admin', 'See the poll')}</span></a></td>
<td><a href="{$poll->admin_id|poll_url:true|html}" class="btn btn-link"
<td><a href="{poll_url id=$poll->admin_id admin=true}" class="btn btn-link"
title="{__('Admin', 'Change the poll')}"><span
class="glyphicon glyphicon-pencil"></span><span
class="sr-only">{__('Admin', 'Change the poll')}</span></a></td>

View File

@ -1,7 +1,7 @@
{extends file='page.tpl'}
{block name=main}
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
<div class="alert alert-danger text-center">
<h2>{__('adminstuds', 'Confirm removal of all comments of the poll')}</h2>
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep the comments')}</button>

View File

@ -1,7 +1,7 @@
{extends file='page.tpl'}
{block name=main}
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
<div class="alert alert-danger text-center">
<h2>{__('adminstuds', 'Confirm removal of the poll')}</h2>
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep the poll')}</button>

View File

@ -1,7 +1,7 @@
{extends file='page.tpl'}
{block name=main}
<form action="{$admin_poll_id|poll_url:true|html}" method="POST">
<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">
<div class="alert alert-danger text-center">
<h2>{__('adminstuds', 'Confirm removal of all votes of the poll')}</h2>
<p><button class="btn btn-default" type="submit" name="cancel">{__('adminstuds', 'Keep votes')}</button>

View File

@ -51,7 +51,7 @@
{if $demo_poll != null}
<p>
{__('1st section', 'Do you want to')}
<a href="{'aqg259dth55iuhwm'|poll_url}">{__('1st section', 'view an example?')}</a>
<a href="{poll_url id='aqg259dth55iuhwm'}">{__('1st section', 'view an example?')}</a>
</p>
{/if}
</div>

View File

@ -1,6 +1,6 @@
{$admin = $admin|default:false}
{if $admin}<form action="{$admin_poll_id|poll_url:true}" method="POST">{/if}
{if $admin}<form action="{poll_url id=$admin_poll_id admin=true}" method="POST">{/if}
<div class="jumbotron{if $admin} bg-danger{/if}">
<div class="row">
<div id="title-form" class="col-md-7">
@ -90,13 +90,13 @@
<div class="row">
<div class="form-group form-group {if $admin}col-md-4{else}col-md-6{/if}">
<label for="public-link"><a class="public-link" href="{$poll_id|poll_url|html}">{__('PollInfo', 'Public link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
<input class="form-control" id="public-link" type="text" readonly="readonly" value="{$poll_id|poll_url}" />
<label for="public-link"><a class="public-link" href="{poll_url id=$poll_id}">{__('PollInfo', 'Public link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
<input class="form-control" id="public-link" type="text" readonly="readonly" value="{poll_url id=$poll_id}" />
</div>
{if $admin}
<div class="form-group col-md-4">
<label for="admin-link"><a class="admin-link" href="{$admin_poll_id|poll_url:true|html}">{__('PollInfo', 'Admin link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
<input class="form-control" id="admin-link" type="text" readonly="readonly" value="{$admin_poll_id|poll_url:true|html}" />
<label for="admin-link"><a class="admin-link" href="{poll_url id=$admin_poll_id admin=true}">{__('PollInfo', 'Admin link of the poll')} <span class="btn-link glyphicon glyphicon-link"></span></a></label>
<input class="form-control" id="admin-link" type="text" readonly="readonly" value="{poll_url id=$admin_poll_id admin=true}" />
</div>
<div id="expiration-form" class="form-group col-md-4">
<h4 class="control-label">{__('PollInfo', 'Expiration date')}</h4>

View File

@ -5,7 +5,7 @@
<h3>{__('Poll results', 'Votes of the poll')}</h3>
<div id="tableContainer" class="tableContainer">
<form action="" method="POST" id="poll_form">
<form action="{poll_url id=$poll_id}" method="POST" id="poll_form">
<table class="results">
<caption class="sr-only">{__('Poll results', 'Votes of the poll')} {$poll->title|html}</caption>
<thead>
@ -35,8 +35,7 @@
<tr>
{* Edited line *}
{if $editingVoteId == $vote->id}
{if $editingVoteId === $vote->uniqId}
<td class="bg-info" style="padding:5px">
<div class="input-group input-group-sm">
<span class="input-group-addon"><span class="glyphicon glyphicon-user"></span></span>
@ -50,19 +49,19 @@
<ul class="list-unstyled choice">
<li class="yes">
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" {if $choice==2}checked {/if}/>
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')} {$slots[$id]->title|html}">
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')|html} {$slots[$id]->title|html}">
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Genric', 'Yes')}</span>
</label>
</li>
<li class="ifneedbe">
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1" {if $choice==1}checked {/if}/>
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')} {$slots[$id]->title|html}">
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slots[$id]->title|html}">
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Genric', 'Ifneedbe')}</span>
</label>
</li>
<li class="no">
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0" {if $choice==0}checked {/if}/>
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')} {$slots[$id]->title|html}">
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slots[$id]->title|html}">
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Genric', 'No')}</span>
</label>
</li>
@ -71,7 +70,6 @@
{/foreach}
<td style="padding:5px"><button type="submit" class="btn btn-success btn-xs check-name" name="save" value="{$vote->id|html}" title="{__('Poll results', 'Save the choices')} {$vote->name|html}">{__('Generic', 'Save')}</button></td>
{else}
{* Voted line *}
<th class="bg-info">{$vote->name|html}</th>
@ -90,11 +88,11 @@
{if $active && $poll->editable && !$expired}
<td>
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{__('Poll results', 'Edit the line:')} {$vote->name|html}">
<a href="{poll_url id=$poll->id vote_id=$vote->uniqId}" class="btn btn-link btn-sm" title="{__('Poll results', 'Edit the line:')|html} {$vote->name|html}">
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
</button>
</a>
{if $admin}
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')|html} {$vote->name|html}">
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
</button>
{/if}
@ -108,7 +106,7 @@
{* Line to add a new vote *}
{if $active && $editingVoteId == 0 && !$expired}
{if $active && $editingVoteId === 0 && !$expired}
<tr id="vote-form">
<td class="bg-info" style="padding:5px">
<div class="input-group input-group-sm">
@ -121,19 +119,19 @@
<ul class="list-unstyled choice">
<li class="yes">
<input type="radio" id="y-choice-{$id}" name="choices[{$id}]" value="2" />
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')} {$slot->title|html}">
<label class="btn btn-default btn-xs" for="y-choice-{$id}" title="{__('Poll results', 'Vote yes for')|html} {$slot->title|html}">
<span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Yes')}</span>
</label>
</li>
<li class="ifneedbe">
<input type="radio" id="i-choice-{$id}" name="choices[{$id}]" value="1" />
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')} {$slot->title|html}">
<label class="btn btn-default btn-xs" for="i-choice-{$id}" title="{__('Poll results', 'Vote ifneedbe for')|html} {$slot->title|html}">
(<span class="glyphicon glyphicon-ok"></span>)<span class="sr-only">{__('Generic', 'Ifneedbe')}</span>
</label>
</li>
<li class="no">
<input type="radio" id="n-choice-{$id}" name="choices[{$id}]" value="0" checked/>
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')} {$slot->title|html}">
<label class="btn btn-default btn-xs" for="n-choice-{$id}" title="{__('Poll results', 'Vote no for')|html} {$slot->title|html}">
<span class="glyphicon glyphicon-ban-circle"></span><span class="sr-only">{__('Generic', 'No')}</span>
</label>
</li>

View File

@ -5,7 +5,7 @@
<h3>{__('Poll results', 'Votes of the poll')}</h3>
<div id="tableContainer" class="tableContainer">
<form action="" method="POST" id="poll_form">
<form action="{poll_url id=$poll_id}" method="POST" id="poll_form">
<table class="results">
<caption class="sr-only">{__('Poll results', 'Votes of the poll')} {$poll->title|html}</caption>
<thead>
@ -81,7 +81,7 @@
<tr>
{* Edited line *}
{if $editingVoteId == $vote->id && !$expired}
{if $editingVoteId === $vote->uniqId && !$expired}
<td class="bg-info" style="padding:5px">
<div class="input-group input-group-sm">
@ -136,9 +136,9 @@
{if $active && $poll->editable && !$expired}
<td>
<button type="submit" class="btn btn-link btn-sm" name="edit_vote" value="{$vote->id|html}" title="{__('Poll results', 'Edit the line:')} {$vote->name|html}">
<a href="{poll_url id=$poll->id vote_id=$vote->uniqId}" class="btn btn-link btn-sm" title="{__('Poll results', 'Edit the line:')|escape} {$vote->name|html}">
<span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span>
</button>
</a>
{if $admin}
<button type="submit" class="btn btn-link btn-sm" name="delete_vote" value="{$vote->id|html}" title="{__('Poll results', 'Remove the line:')} {$vote->name|html}">
<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">{__('Generic', 'Remove')}</span>
@ -154,7 +154,7 @@
{* Line to add a new vote *}
{if $active && $editingVoteId == 0 && !$expired}
{if $active && $editingVoteId === 0 && !$expired}
<tr id="vote-form">
<td class="bg-info" style="padding:5px">
<div class="input-group input-group-sm">