1 package Newslash::Model::Polls;
2 use Newslash::Model::Base -base;
3 use Newslash::Model::Polls::Voters;
9 return $self->generic_count(table => "pollquestions",
16 return shift->new_instance_of("::Polls::Answers");
20 return shift->new_instance_of("::Polls::Voters");
27 my $unique_keys = { question_id => "pollquestions.qid",
28 qid => "pollquestions.qid",
29 id => "pollquestions.qid",
30 discussion => "pollquestions.discussion",
31 discussion_id => "pollquestions.discussion",
33 my $keys = { create_time => "pollquestions.date",
34 voters => "pollquestions.voters",
36 my $datetime_keys = { create_time => "pollquestions.date",
38 my $timestamp = "pollquestions.date";
40 my ($where_clause, $where_values, $unique) = $self->build_where_clause(unique_keys => $unique_keys,
42 datetime_keys => $datetime_keys,
43 timestamp => $timestamp,
45 my ($limit_clause, $limit_values) = $self->build_limit_clause(params => $params);
46 my ($orderby_clause, $orderby_values) = $self->build_order_by_clause(keys => $keys,
49 $limit_clause = "LIMIT 20" if !$limit_clause;
53 if (!$params->{show_future}) {
54 push @where_clauses, "pollquestions.date <= NOW()";
58 $where_clause = $where_clause . " AND ";
61 $where_clause = "WHERE ";
63 $where_clause = $where_clause . join(" AND ", @where_clauses);
67 push @attrs, @$where_values, @$limit_values, @$orderby_values;
70 SELECT pollquestions.*,
71 users.nickname AS author,
73 discussions.type AS discussion_type, discussions.commentcount AS comment_count
75 LEFT JOIN users ON pollquestions.uid = users.uid
76 LEFT JOIN discussions ON pollquestions.discussion = discussions.id
77 LEFT JOIN topics ON pollquestions.topic = topics.tid
83 my $dbh = $self->connect_db;
84 my $sth = $dbh->prepare($sql);
85 $sth->execute(@attrs);
86 my $polls = $sth->fetchall_arrayref(+{});
88 $self->disconnect_db();
91 $self->disconnect_db();
93 for my $poll (@$polls) {
94 $self->_generalize($poll);
95 my $answers = $self->generic_select(table => "pollanswers",
96 keys => [qw(qid aid)],
99 order_by => { aid => 'ASC' },
102 $poll->{answers} = $answers;
103 $self->_calc_percentage($answers);
113 sub _calc_percentage {
114 my ($self, $answers) = @_;
116 for my $answer (@$answers) {
117 $total += $answer->{votes};
119 for my $answer (@$answers) {
121 $answer->{percentage} = int(100 * $answer->{votes} / $total);
127 my ($self, $user, $params) = @_;
128 return if $self->check_readonly;
129 return if !$user || !$params;
132 INSERT INTO pollquestions
133 (question, voters, topic, date, uid, primaryskid)
135 (?, 0, ?, NOW(), ?, ?)
138 my $dbh = $self->start_transaction;
139 my $rs = $dbh->do($sql,
146 $self->set_error("insert question failed", $dbh->{mysql_errorno});
150 my $qid = $dbh->last_insert_id(undef, undef, undef, undef);
153 INSERT INTO pollanswers
154 (qid, aid, answer, votes)
160 for my $answer (@{$params->{answers}}) {
161 my $rs = $dbh->do($sql, undef, $qid, $aid, $answer);
163 $self->set_error("insert answer failed", $dbh->{mysql_errorno});
175 my ($self, $user, $qid, $aid) = @_;
176 my $uid = $user ? $user->{uid} : 0;
179 $self->set_error("invalid user");
182 my $poll = $self->select(question_id => $qid || 0);
184 $self->set_error("poll not found");
188 my $is_valid_answer = 0;
190 for my $answer (@{$poll->{answers}}) {
191 if ($aid == $answer->{aid}) {
192 $is_valid_answer = 1;
197 if (!$is_valid_answer) {
198 $self->set_error("invalid answer");
203 if ($user->{is_login}) {
204 my $voters = $self->voters;
205 my $votes = $voters->select(question_id => $qid, user_id => $uid);
207 $self->set_error("select voters failed", $voters->last_errorno);
211 $self->set_error("already voted");
218 UPDATE pollanswers SET votes = votes + 1 WHERE qid = ? AND aid = ?
221 my $dbh = $self->start_transaction;
222 my $rs = $dbh->do($sql, undef, $qid, $aid);
224 $self->set_error("update pollanswers failed", $dbh->{mysql_errorno});
230 UPDATE pollquestions SET voters = voters + 1 WHERE qid = ?
233 $rs = $dbh->do($sql, undef, $qid);
235 $self->set_error("update pollquestions failed", $dbh->{mysql_errorno});
241 INSERT INTO pollvoters
247 my $net_id = $user->{ipid} || "";
249 $rs = $dbh->do($sql, undef, $qid, $net_id, $uid);
251 $self->set_error("insert into pollvoters failed", $dbh->{mysql_errorno});
261 my ($self, $qid) = @_;
264 my $sql = "DELETE FROM pollanswers WHERE qid = ?";
266 my $dbh = $self->start_transaction;
267 my $rs = $dbh->do($sql, undef, $qid);
269 $self->set_error("hard-delete answers failed", $dbh->{mysql_errorno});
274 $sql = "DELETE FROM pollquestions WHERE qid = ?";
275 $rs = $dbh->do($sql, undef, $qid);
277 $self->set_error("hard-delete questions failed", $dbh->{mysql_errorno});
282 $sql = "DELETE FROM pollvoters WHERE qid = ?";
283 $rs = $dbh->do($sql, undef, $qid);
285 $self->set_error("hard-delete voters failed", $dbh->{mysql_errorno});
295 my ($self, $poll) = @_;
298 $poll->{id} = $poll->{qid};
299 $poll->{create_time} = $poll->{date};
301 my $primary_topic = {};
302 for my $item (qw(tid keyword textname series image width height submittable searchable storypickable usesprite)) {
303 $primary_topic->{$item} = $poll->{$item};
305 $poll->{primary_topic} = $primary_topic;
306 $poll->{topics} = [$primary_topic,];
308 if ($poll->{topic}) {
309 $poll->{primary_topic} = $poll->{topic};
311 $poll->{content_type} = "poll";
312 $poll->{title} = $poll->{question};
313 $poll->{discussion_id} = $poll->{discussion};
314 $poll->{public} = 'yes';