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",
35 my $datetime_keys = { create_time => "pollquestions.date",
37 my $timestamp = "pollquestions.date";
39 my ($where_clause, $where_values, $unique) = $self->build_where_clause(unique_keys => $unique_keys,
41 datetime_keys => $datetime_keys,
42 timestamp => $timestamp,
44 my ($limit_clause, $limit_values) = $self->build_limit_clause(params => $params);
45 my ($orderby_clause, $orderby_values) = $self->build_order_by_clause(keys => $keys,
48 $limit_clause = "LIMIT 20" if !$limit_clause;
52 if (!$params->{show_future}) {
53 push @where_clauses, "pollquestions.date <= NOW()";
57 $where_clause = $where_clause . " AND ";
60 $where_clause = "WHERE ";
62 $where_clause = $where_clause . join(" AND ", @where_clauses);
66 push @attrs, @$where_values, @$limit_values, @$orderby_values;
69 SELECT pollquestions.*,
70 users.nickname AS author,
72 discussions.type AS discussion_type, discussions.commentcount AS comment_count
74 LEFT JOIN users ON pollquestions.uid = users.uid
75 LEFT JOIN discussions ON pollquestions.discussion = discussions.id
76 LEFT JOIN topics ON pollquestions.topic = topics.tid
82 my $dbh = $self->connect_db;
83 my $sth = $dbh->prepare($sql);
84 $sth->execute(@attrs);
85 my $polls = $sth->fetchall_arrayref(+{});
87 $self->disconnect_db();
90 $self->disconnect_db();
92 for my $poll (@$polls) {
93 $self->_generalize($poll);
94 my $answers = $self->generic_select(table => "pollanswers",
95 keys => [qw(qid aid)],
98 order_by => { aid => 'ASC' },
101 $poll->{answers} = $answers;
102 $self->_calc_percentage($answers);
112 sub _calc_percentage {
113 my ($self, $answers) = @_;
115 for my $answer (@$answers) {
116 $total += $answer->{votes};
118 for my $answer (@$answers) {
120 $answer->{percentage} = int(100 * $answer->{votes} / $total);
126 my ($self, $user, $params) = @_;
127 return if $self->check_readonly;
128 return if !$user || !$params;
131 INSERT INTO pollquestions
132 (question, voters, topic, date, uid, primaryskid)
134 (?, 0, ?, NOW(), ?, ?)
137 my $dbh = $self->start_transaction;
138 my $rs = $dbh->do($sql,
146 $self->set_error("insert question failed", $dbh->{mysql_errorno});
147 $self->disconnect_db;
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);
164 $self->set_error("insert answer failed", $dbh->{mysql_errorno});
165 $self->disconnect_db;
176 my ($self, $user, $qid, $aid) = @_;
177 my $uid = $user ? $user->{uid} : 0;
180 $self->set_error("invalid user");
183 my $poll = $self->select(question_id => $qid || 0);
185 $self->set_error("poll not found");
189 my $is_valid_answer = 0;
191 for my $answer (@{$poll->{answers}}) {
192 if ($aid == $answer->{aid}) {
193 $is_valid_answer = 1;
198 if (!$is_valid_answer) {
199 $self->set_error("invalid answer");
204 if ($user->{is_login}) {
205 my $voters = $self->voters;
206 my $votes = $voters->select(question_id => $qid, user_id => $uid);
208 $self->set_error("select voters failed", $voters->last_errorno);
212 $self->set_error("already voted");
219 UPDATE pollanswers SET votes = votes + 1 WHERE qid = ? AND aid = ?
222 my $dbh = $self->start_transaction;
223 my $rs = $dbh->do($sql, undef, $qid, $aid);
226 $self->set_error("update pollanswers failed", $dbh->{mysql_errorno});
227 $self->disconnect_db;
232 UPDATE pollquestions SET voters = voters + 1 WHERE qid = ?
235 $rs = $dbh->do($sql, undef, $qid);
238 $self->set_error("update pollquestions failed", $dbh->{mysql_errorno});
239 $self->disconnect_db;
244 INSERT INTO pollvoters
250 my $net_id = $user->{ipid} || "";
252 $rs = $dbh->do($sql, undef, $qid, $net_id, $uid);
255 $self->set_error("insert into pollvoters failed", $dbh->{mysql_errorno});
256 $self->disconnect_db;
265 my ($self, $qid) = @_;
268 my $sql = "DELETE FROM pollanswers WHERE qid = ?";
270 my $dbh = $self->start_transaction;
271 my $rs = $dbh->do($sql, undef, $qid);
274 $self->set_error("hard-delete answers failed", $dbh->{mysql_errorno});
275 $self->disconnect_db;
279 $sql = "DELETE FROM pollquestions WHERE qid = ?";
280 $rs = $dbh->do($sql, undef, $qid);
283 $self->set_error("hard-delete questions failed", $dbh->{mysql_errorno});
284 $self->disconnect_db;
288 $sql = "DELETE FROM pollvoters WHERE qid = ?";
289 $rs = $dbh->do($sql, undef, $qid);
292 $self->set_error("hard-delete voters failed", $dbh->{mysql_errorno});
293 $self->disconnect_db;
302 my ($self, $poll) = @_;
305 $poll->{id} = $poll->{qid};
306 $poll->{create_time} = $poll->{date};
308 my $primary_topic = {};
309 for my $item (qw(tid keyword textname series image width height submittable searchable storypickable usesprite)) {
310 $primary_topic->{$item} = $poll->{$item};
312 $poll->{primary_topic} = $primary_topic;
313 $poll->{topics} = [$primary_topic,];
315 if ($poll->{topic}) {
316 $poll->{primary_topic} = $poll->{topic};
318 $poll->{content_type} = "poll";
319 $poll->{title} = $poll->{question};
320 $poll->{discussion_id} = $poll->{discussion};
321 $poll->{public} = 'yes';