[dw-free] Anonymized Detailed Results as a poll option
[commit: http://hg.dwscoalition.org/dw-free/rev/4fcdfd9c7c1c]
http://bugs.dwscoalition.org/show_bug.cgi?id=2363
Allow poll results to be anonymized, so that no one can see the username
that cast each vote. Instead, an automatically generated identifier will be
used (so that it's possible to identify the votes that were cast per set)
Patch by
jportela.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2363
Allow poll results to be anonymized, so that no one can see the username
that cast each vote. Instead, an automatically generated identifier will be
used (so that it's possible to identify the votes that were cast per set)
Patch by
Files modified:
- bin/upgrading/en.dat
- bin/upgrading/update-db-general.pl
- cgi-bin/LJ/Event/PollVote.pm
- cgi-bin/LJ/Poll.pm
- cgi-bin/LJ/Poll/Question.pm
- htdocs/poll/create.bml
- htdocs/poll/create.bml.text
- htdocs/tools/endpoints/poll.bml
--------------------------------------------------------------------------------
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c bin/upgrading/en.dat
--- a/bin/upgrading/en.dat Tue Sep 07 11:19:36 2010 +0800
+++ b/bin/upgrading/en.dat Tue Sep 07 15:28:41 2010 +0800
@@ -2381,6 +2381,8 @@ poll.error.whoview=whoview must be 'all'
poll.error.whovote=whovote must be 'all' or 'friends'.
+poll.isanonymous=This poll is anonymous.
+
poll.isclosed=This poll is closed.
poll.participants=, participants: [[total]]
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl Tue Sep 07 11:19:36 2010 +0800
+++ b/bin/upgrading/update-db-general.pl Tue Sep 07 15:28:41 2010 +0800
@@ -3889,6 +3889,11 @@ EOF
do_alter( 'moods',
q{ALTER TABLE moods ADD COLUMN weight tinyint unsigned default NULL} );
}
+
+ unless ( column_type( 'poll2', 'isanon' ) ) {
+ do_alter( 'poll2',
+ "ALTER TABLE poll2 ADD COLUMN isanon enum('yes','no') NOT NULL default 'no'");
+ }
});
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c cgi-bin/LJ/Event/PollVote.pm
--- a/cgi-bin/LJ/Event/PollVote.pm Tue Sep 07 11:19:36 2010 +0800
+++ b/cgi-bin/LJ/Event/PollVote.pm Tue Sep 07 15:28:41 2010 +0800
@@ -68,21 +68,23 @@ sub pollname {
sub as_string {
my $self = shift;
+
+ my $voter = ($self->poll->isanon eq "yes") ? "Anonymous user" : $self->voter->display_username;
return sprintf("%s has voted in %s at %s",
- $self->voter->display_username, $self->pollname, $self->entry->url);
+ $voter, $self->pollname, $self->entry->url);
}
sub as_html {
my $self = shift;
- my $voter = $self->voter;
+ my $voter = ($self->poll->isanon eq "yes") ? "Anonymous user" : $self->voter->ljuser_display;
my $poll = $self->poll;
- return sprintf("%s has voted in a deleted poll", $voter->ljuser_display)
+ return sprintf("%s has voted in a deleted poll", $voter)
unless $poll && $poll->valid;
my $entry = $self->entry;
return sprintf("%s has voted <a href='%s'>in %s</a>",
- $voter->ljuser_display, $entry->url, $self->pollname);
+ $voter, $entry->url, $self->pollname);
}
sub as_html_actions {
@@ -122,10 +124,11 @@ sub as_email_subject {
sub _as_email {
my ($self, $u, $is_html) = @_;
+ my $voter = $is_html ? ($self->voter->ljuser_display) : ($self->voter->display_username);
my $vars = {
user => $is_html ? ($u->ljuser_display) : ($u->display_username),
- voter => $is_html ? ($self->voter->ljuser_display) : ($self->voter->display_username),
+ voter => ($self->poll->isanon eq "yes") ? "Anonymous user" : $voter,
pollname => $self->pollname,
};
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c cgi-bin/LJ/Poll.pm
--- a/cgi-bin/LJ/Poll.pm Tue Sep 07 11:19:36 2010 +0800
+++ b/cgi-bin/LJ/Poll.pm Tue Sep 07 15:28:41 2010 +0800
@@ -28,9 +28,9 @@ sub _memcache_stored_props {
sub _memcache_stored_props {
# first element of props is a VERSION
# next - allowed object properties
- return qw/ 1
+ return qw/ 2
ditemid itemid
- pollid journalid posterid whovote whoview name status questions props
+ pollid journalid posterid isanon whovote whoview name status questions props
/;
}
*_memcache_hashref_to_object = \*absorb_row;
@@ -78,7 +78,8 @@ sub create {
$journalid = $opts{journalid} or croak "No journalid";
$posterid = $opts{posterid} or croak "No posterid";
}
-
+
+ my $isanon = $opts{isanon} or croak "No isanon";
my $whovote = $opts{whovote} or croak "No whovote";
my $whoview = $opts{whoview} or croak "No whoview";
my $name = $opts{name} || '';
@@ -98,9 +99,9 @@ sub create {
my $dbh = LJ::get_db_writer();
- $u->do( "INSERT INTO poll2 (journalid, pollid, posterid, whovote, whoview, name, ditemid) " .
- "VALUES (?, ?, ?, ?, ?, ?, ?)", undef,
- $journalid, $pollid, $posterid, $whovote, $whoview, $name, $ditemid );
+ $u->do( "INSERT INTO poll2 (journalid, pollid, posterid, isanon, whovote, whoview, name, ditemid) " .
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", undef,
+ $journalid, $pollid, $posterid, $isanon, $whovote, $whoview, $name, $ditemid );
die $u->errstr if $u->err;
# made poll, insert global pollid->journalid mapping into global pollowner map
@@ -252,6 +253,7 @@ sub new_from_html {
$popts{'questions'} = [];
$popts{'name'} = $opts->{'name'};
+ $popts{'isanon'} = $opts->{'isanon'} || "no";
$popts{'whovote'} = lc($opts->{'whovote'}) || "all";
$popts{'whoview'} = lc($opts->{'whoview'}) || "all";
@@ -267,7 +269,9 @@ sub new_from_html {
$popts{props}->{createdate} = $opts->{createdate} || undef;
}
LJ::Hooks::run_hook('get_more_options_from_poll', finalopts => \%popts, givenopts => $opts, journalu => $journal);
-
+
+ $popts{'isanon'} = "no" unless ($popts{'isanon'} eq "yes");
+
if ($popts{'whovote'} ne "all" &&
$popts{'whovote'} ne "trusted")
{
@@ -529,7 +533,7 @@ sub save_to_db {
$createopts{name} = $opts{name} || $self->{name};
$createopts{props} = $opts{props} || $self->{props};
- foreach my $f (qw(ditemid journalid posterid questions whovote whoview)) {
+ foreach my $f (qw(ditemid journalid posterid questions isanon whovote whoview)) {
$createopts{$f} = $opts{$f} || $self->{$f} or croak "Field $f required for save_to_db";
}
@@ -567,7 +571,7 @@ sub _load {
or die "Invalid journalid $journalid";
$row = $u->selectrow_hashref( "SELECT pollid, journalid, ditemid, " .
- "posterid, whovote, whoview, name, status " .
+ "posterid, isanon, whovote, whoview, name, status " .
"FROM poll2 WHERE pollid=? " .
"AND journalid=?", undef, $self->pollid, $journalid );
die $u->errstr if $u->err;
@@ -590,7 +594,7 @@ sub absorb_row {
# questions is an optional field for creating a fake poll object for previewing
$self->{ditemid} = $row->{ditemid} || $row->{itemid}; # renamed to ditemid in poll2
- $self->{$_} = $row->{$_} foreach qw(pollid journalid posterid whovote whoview name status questions props);
+ $self->{$_} = $row->{$_} foreach qw(pollid journalid posterid isanon whovote whoview name status questions props);
$self->{_loaded} = 1;
return $self;
}
@@ -652,6 +656,11 @@ sub name {
my $self = shift;
$self->_load;
return $self->{name};
+}
+sub isanon {
+ my $self = shift;
+ $self->_load;
+ return $self->{isanon};
}
sub whovote {
my $self = shift;
@@ -774,6 +783,9 @@ sub preview {
$ret .= "<br />\n";
+ $ret .= "This poll is <b>anonymous</b><br/>\n"
+ if ($self->isanon eq "yes");
+
my $whoview = $self->whoview eq "none" ? "none_remote" : $self->whoview;
$ret .= LJ::Lang::ml('poll.security2', { 'whovote' => LJ::Lang::ml('poll.security.'.$self->whovote), 'whoview' => LJ::Lang::ml('poll.security.'.$whoview), });
@@ -857,7 +869,7 @@ sub render {
my $text = $q->text;
LJ::Poll->clean_poll(\$text);
$ret .= $text;
- $ret .= '<div>' . $q->answers_as_html($self->journalid, $page, $pagesize) . '</div>';
+ $ret .= '<div>' . $q->answers_as_html($self->journalid, $self->isanon, $page, $pagesize) . '</div>';
return $ret;
}
@@ -897,6 +909,9 @@ sub render {
$ret .= "<span style='font-family: monospace; font-weight: bold; font-size: 1.2em;'>" .
LJ::Lang::ml( 'poll.isclosed' ) . "</span><br />\n"
if ($self->is_closed);
+
+ $ret .= "This poll is <b>anonymous</b><br/>\n"
+ if ($self->isanon eq "yes");
my $whoview = $self->whoview;
if ($whoview eq "none") {
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c cgi-bin/LJ/Poll/Question.pm
--- a/cgi-bin/LJ/Poll/Question.pm Tue Sep 07 11:19:36 2010 +0800
+++ b/cgi-bin/LJ/Poll/Question.pm Tue Sep 07 15:28:41 2010 +0800
@@ -219,6 +219,7 @@ sub answers_as_html {
sub answers_as_html {
my $self = shift;
my $jid = shift;
+ my $isanon = shift;
my $page = shift || 1;
my $pagesize = shift || 2000;
@@ -236,6 +237,7 @@ sub answers_as_html {
"WHERE pr.pollid=? AND pollqid=? " .
"AND ps.pollid=pr.pollid AND ps.userid=pr.userid " .
"AND ps.journalid=? ".
+ "ORDER BY ps.datesubmit " .
"LIMIT $LIMIT" );
$sth->execute( $self->pollid, $self->pollqid, $jid );
die $sth->errstr if $sth->err;
@@ -245,7 +247,8 @@ sub answers_as_html {
my @res;
push @res, $_ while $_ = $sth->fetchrow_hashref;
@res = sort { $a->{datesubmit} cmp $b->{datesubmit} } @res;
-
+
+ my $user_i = 0; #incrementer for user anonymous ids
foreach my $res (@res) {
my ($userid, $value) = ($res->{userid}, $res->{value}, $res->{pollqid});
my @items = $self->items;
@@ -263,7 +266,9 @@ sub answers_as_html {
}
LJ::Poll->clean_poll(\$value);
- $ret .= "<div>" . $u->ljuser_display . " -- $value</div>\n";
+ my $user_display = $isanon eq "yes" ? "User <b>#" . ++$user_i . "</b>" : $u->ljuser_display;
+
+ $ret .= "<div>" . $user_display . " -- $value</div>\n";
}
return $ret;
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c htdocs/poll/create.bml
--- a/htdocs/poll/create.bml Tue Sep 07 11:19:36 2010 +0800
+++ b/htdocs/poll/create.bml Tue Sep 07 15:28:41 2010 +0800
@@ -146,6 +146,7 @@ _c?>
my $poll = {
"name" => "",
"count" => "0",
+ "isanon" => "no",
"whoview" => "all",
"whovote" => "all",
"pq" => [],
@@ -157,7 +158,7 @@ _c?>
if $POST{'count'} > $RULES{'elements'}->{'max'};
# form properties
- foreach my $it (qw(count name whoview whovote)) {
+ foreach my $it (qw(count name isanon whoview whovote)) {
$poll->{$it} = $POST{$it} if $POST{$it};
}
@@ -403,11 +404,20 @@ _c?>
$ret .= "<div style='margin: 10px 0 20px 40px'><b>$ML{'.haserrors'}</b></div>\n"
if %$err;
- ### Poll Properties -- name, whovote, whoview
+ ### Poll Properties -- name, isanon, whovote, whoview
$ret .= "<?h1 $ML{'.properties'} h1?>\n";
$ret .= "<div style='margin-left: 40px; margin-bottom: 20px'>\n";
+
+ $ret .= "<p>" . LJ::html_check({
+ name => 'isanon',
+ id => 'isanon',
+ label => $ML{'.isanon'},
+ value => "yes",
+ selected => ( $poll->{isanon} eq "yes" )
+ }) . "</p>\n";
+
$ret .= "<p>$ML{'.whoview2'}<br /><select name='whoview'>\n";
foreach my $sec ( qw(all trusted none) ) {
$ret .= "<option value='$sec'";
@@ -576,7 +586,7 @@ _c?>
my $ret;
# start out the tag
- $ret .= "<poll name='" . LJ::ehtml($poll->{'name'}) . "' whovote='" . LJ::ehtml($poll->{'whovote'}) . "' whoview='" . LJ::ehtml($poll->{'whoview'}) . "'>\n";
+ $ret .= "<poll name='" . LJ::ehtml($poll->{'name'}) . "' isanon='" . $poll->{'isanon'} . "' whovote='" . LJ::ehtml($poll->{'whovote'}) . "' whoview='" . LJ::ehtml($poll->{'whoview'}) . "'>\n";
# go through and make <poll-question> tags
foreach my $q (0..$poll->{'count'}-1) {
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c htdocs/poll/create.bml.text
--- a/htdocs/poll/create.bml.text Tue Sep 07 11:19:36 2010 +0800
+++ b/htdocs/poll/create.bml.text Tue Sep 07 15:28:41 2010 +0800
@@ -39,6 +39,8 @@
.insertquestion=Insert question here:
+.isanon=Anonymize poll results. No one can see who voted, not even you.
+
.options=Options:
.options.limitreached=Option limit reached
diff -r 7f28d1bf7c09 -r 4fcdfd9c7c1c htdocs/tools/endpoints/poll.bml
--- a/htdocs/tools/endpoints/poll.bml Tue Sep 07 11:19:36 2010 +0800
+++ b/htdocs/tools/endpoints/poll.bml Tue Sep 07 15:28:41 2010 +0800
@@ -49,7 +49,7 @@ _c?>
my $question = $poll->question($pollqid) or return $err->("Error loading question $pollqid");
my $pages = $question->answers_pages($poll->journalid, $pagesize);
$ret->{paging_html} = $question->paging_bar_as_html($page, $pages, $pagesize, $poll->journalid, $pollid, $pollqid);
- $ret->{answer_html} = $question->answers_as_html($poll->journalid, $page, $pagesize, $pages);
+ $ret->{answer_html} = $question->answers_as_html($poll->journalid, $poll->isanon, $page, $pagesize, $pages);
} else {
return $err->("Invalid action $action");
}
--------------------------------------------------------------------------------

no subject
no subject
no subject