/Vector/Post.pm
use CGI::Fast qw/:standard/;
use Vector::DB;
use Vector::User;
use Vector::Channel;
use Vector::Thread;
use Vector::Util qw/simplify_uri xmlescape/;
use Vector::Config qw/$webroot $thumbdir $datadir/;
use Vector::Notify;
use Vector::ReplyTag;
use Vector::HtmlFilter;
use strict;
{
my ($class, $user_id, $channel_id, $data, $file, $replyto) = @_;
Vector::HtmlFilter::htmlfilter \$data;
my $self = {
type => 'post',
user_id => $user_id,
channel_id => $channel_id,
data => $data,
file => $file,
replyto => $replyto,
user => Vector::User->fetch_by_id($user_id),
channel => Vector::Channel::name($channel_id),
root => not defined $replyto,
};
return bless $self, $class;
}
{
my ($class, $post_id) = @_;
my $dbh = Vector::DB::connect;
my $self = $dbh->selectrow_hashref('SELECT user_id, channel_id, data, file, replyto FROM posts WHERE post_id = ?', undef, $post_id);
$self->{} = 'post';
$self->{} = Vector::User->fetch_by_id($self->{});
$self->{} = Vector::Channel::name($self->{});
$self->{} = $post_id;
$self->{} = fetch Vector::Thread($self->{} || $self->{});
$self->{} = not defined $self->{};
return bless $self, $class;
}
{
my ($self) = @_;
my $dbh = Vector::DB::connect;
Vector::HtmlFilter::htmlfilter \$self->{};
if ($self->{}) {
$dbh->do('UPDATE posts set data, ts) VALUES (?,NOW())', undef, $self->{})
or die $dbh->errstr;
} else {
$dbh->do('INSERT INTO posts (user_id, channel_id, data, file, replyto, ts) VALUES (?,?,?,?,?,NOW())', undef, $self->{}, $self->{}, $self->{}, $self->{}, $self->{})
or die $dbh->errstr;
# Ick, MySQL-ism
($self->{}) = $dbh->selectrow_array('SELECT LAST_INSERT_ID()');
if ($self->{}) {
$self->{} = fetch Vector::Thread($self->{});
$self->{}->update;
} else {
$self->{} = new Vector::Thread($self->{});
}
}
Vector::Channel::update($self->{});
$self->notify;
return $self->{};
}
{
my ($self, %opts) = @_;
my $dbh = Vector::DB::connect;
if (defined $opts{}) {
$opts{} = 0 unless defined $opts{};
return @{$dbh->selectcol_arrayref('SELECT post_id FROM posts WHERE replyto = ? ORDER BY ts DESC LIMIT ? OFFSET ?', undef, $self->{}, $opts{}, $opts{})};
} else {
return @{$dbh->selectcol_arrayref('SELECT post_id FROM posts WHERE replyto = ? ORDER BY ts DESC', undef, $self->{})};
}
}
{
my ($self) = @_;
my $dbh = Vector::DB::connect;
my ($n) = $dbh->selectrow_array('SELECT count(*) FROM posts WHERE replyto = ?', undef, $self->{});
return $n;
}
{
my ($self) = @_;
my $r;
if ($self->{}) {
my ($file_id, $filename) = split(m'/', $self->{});
if (-e "$datadir/$self->{file}") {
my $thumburi;
if (-d "$thumbdir/$file_id") {
$thumburi = "${webroot}thumb/$file_id/thumbnail.jpg";
} else {
$thumburi = "${webroot}static/unknown-document.png";
}
$r .= a({href => "${webroot}data/$self->{file}", alt => $filename, title => $filename}, img({src => $thumburi, align => 'left'}));
$r .= "\n";
}
}
$r .= Vector::Util::linebreak($self->{});
return $r;
}
{
my ($self, $child_limit) = @_;
my (@controls);
my $shortname = simplify_uri $self->{}->{};
my $user_url = $self->{}->user_url;
my $content = $self->content;
if (defined $child_limit && $self->{}) {
push @controls, qq{<a href="${webroot}channel/$self->{channel}/$self->{post_id}">full thread</a>};
}
my $count_replies = $self->count_replies;
my @replies = reverse $self->replies(limit => $child_limit);
my @things;
if ($count_replies > @replies) {
push @things, qq{<li><a href="${webroot}channel/$self->{channel}/$self->{post_id}">... }, $count_replies - @replies, ' more replies</a></li>';
}
for my $r (@replies) {
my $post = load Vector::Post($r);
push @things, $post->format;
}
if ($self->{} && $main::login_id) {
Delete('replyto');
my @expando = (-onfocus => 'reply_expand(this.parentNode)', -onblur => 'reply_compact(this.parentNode)');
my $form_options = {};
if (defined $child_limit) {
$form_options->{} = 'compact';
}
push @things,
'<li>' .
start_form($form_options) .
hidden('replyto', $self->{}) .
textarea(-name => 'data', @expando) . br .
filefield(-name => 'file', @expando) . br .
submit(-name => 'Reply', @expando) .
end_form .
'</li>';
}
return <<EOD;
<li><a name="post$self->{post_id}"></a>
<div>
<div class="controls">@controls</div>
<h2><a href="$user_url">$shortname</a></h2>
$content
<div style="clear: both"></div>
</div>
@{[ @things ? "<ul>@things</ul>" : '' ]}
</li>
EOD
}
{
my ($self, $child_limit) = @_;
print $self->format($child_limit);
}
{
my ($self) = @_;
my $replytag = Vector::ReplyTag::create($self);
my $display_username = simplify_uri($self->{}->{});
Vector::Notify::queue(<<EOD, $self->{channel_id}, $self->{thread}->{post_id});
From $display_username $replytag
$self->{data}
EOD
}
{
my ($self) = @_;
return "${webroot}channel/$self->{channel}/$self->{thread}->{post_id}#post$self->{post_id}";
}
{
my ($self) = @_;
return "${webroot}channel/$self->{channel}/$self->{thread}->{post_id}";
}
1;