diff --git a/Bug.pm b/Bug.pm index da64d9b..5271203 100644 --- a/Bug.pm +++ b/Bug.pm @@ -15,9 +15,16 @@ status varchar NOT NULL DEFAULT '', closed boolean NOT NULL DEFAULT false, email varchar NOT NULL DEFAULT '', - message varchar NOT NULL DEFAULT '' + message varchar NOT NULL DEFAULT '', + admin boolean NOT NULL DEFAULT false, + name varchar(200) NOT NULL DEFAULT '' ); +=head2 Update queries + + ALTER TABLE ${p}messages ADD COLUMN admin boolean NOT NULL DEFAULT false; + ALTER TABLE ${p}messages ADD COLUMN name varchar(200) NOT NULL DEFAULT ''; + =cut # TODO: Atom feed? @@ -71,7 +78,7 @@ sub dbListing { sub dbItem { my($self, $id) = @_; return $TUWF::OBJ->dbAll(q{ - SELECT m.issue, m.summary, to_char(m.date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, m.type, m.status, m.closed, m.message + SELECT m.issue, m.summary, to_char(m.date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, m.type, m.status, m.closed, m.name, m.admin, m.message FROM !smessages m WHERE m.issue = ? ORDER BY m.id}, $self->{prefix}, $id @@ -89,7 +96,7 @@ sub dbSave { my($self, $id, $closed, @a) = @_; $id = $TUWF::OBJ->dbRow('INSERT INTO !sissues (latest) VALUES (0) RETURNING issue', $self->{prefix})->{issue} if !$id; my $latest = $TUWF::OBJ->dbRow( - 'INSERT INTO !smessages (issue, closed, summary, email, type, status, message) VALUES (?, ?, !l) RETURNING id', + 'INSERT INTO !smessages (issue, closed, summary, name, email, type, status, message, admin) VALUES (?, ?, !l) RETURNING id', $self->{prefix}, $id, $closed?1:0, \@a )->{id}; $TUWF::OBJ->dbExec('UPDATE !sissues SET latest = ? WHERE issue = ?', $self->{prefix}, $latest, $id); @@ -150,7 +157,12 @@ sub htmlItem { div class => 'bug_message'; h1 !++$num ? 'Description' : "Reply $num"; dl; - dt !$num ? 'Created' : 'Added'; dd $m->{date}; + dt !$num ? 'Created' : 'Added'; + dd; + txt "$m->{date} by "; + txt $m->{name}||'Anonymous' if !$m->{admin}; + b $m->{name}||'Admin' if $m->{admin}; + end; for($num ? qw|summary type status| : ()) { if($m->{$_} ne $d->[$num-1]{$_}) { dt "\u$_"; @@ -181,9 +193,15 @@ sub htmlForm { label for => 'bug_summary', 'Summary'; input type => 'text', name => 'bug_summary', id => 'bug_summary', size => 45, value => $l?$l->{summary}:''; end; + li class => 'bug_frm_name'; + label for => 'bug_name', 'Name'; + input type => 'text', name => 'bug_name', id => 'bug_name', size => 20, value => $TUWF::OBJ->reqCookie('bug_name')||''; + lit ' '; + txt 'Name+email will be remembered with a cookie.'; + end; li class => 'bug_frm_mail'; label for => 'bug_email', 'Email'; - input type => 'text', name => 'bug_email', id => 'bug_email', size => 20; + input type => 'text', name => 'bug_email', id => 'bug_email', size => 20, value => $TUWF::OBJ->reqCookie('bug_email')||''; lit ' '; txt 'Optional, only used for notifications.'; end; @@ -200,7 +218,7 @@ sub htmlForm { option value => 0, !$l->{closed} ? (selected => 'selected') : (), 'Open'; option value => 1, $l->{closed} ? (selected => 'selected') : (), 'Closed'; end; - input type => 'password', name => 'bug_code', id => 'bug_code', size => 10, value => 'code'; + input type => 'password', name => 'bug_code', id => 'bug_code', size => 10, value => $TUWF::OBJ->reqCookie('bug_code')||'code'; end; } else { li class => 'bug_frm_type'; @@ -228,12 +246,16 @@ sub handleForm { my $f = $TUWF::OBJ->formValidate( { post => 'bug_id', min => 0 }, { post => 'bug_summary', maxlength => 200, minlength => 2 }, + { post => 'bug_name', required => 0, default => '', maxlength => 200 }, { post => 'bug_email', required => 0, regex => qr/^[^@<>]+@[^@.<>]+(?:\.[^@.<>]+)+$/ }, { post => 'bug_code', required => 0, default => '' }, { post => 'bug_message', maxlength => 256*1024, minlength => 1 }, ); return($f, undef) if $f->{_err}; + $f->{bug_code} = '' if $f->{bug_code} eq 'code'; + my $admin = grep($_ eq $f->{bug_code}, @{$s->{admins}}) ? 1 : 0; + my $l; # Reply if($f->{bug_id} > 0) { @@ -241,7 +263,7 @@ sub handleForm { push @{$f->{_err}}, ['bug_id', 'db_check', ''] and return($f, undef) if !$l; # Check admin things - if(grep $_ eq $f->{bug_code}, @{$s->{admins}}) { + if($admin) { my $fa = $TUWF::OBJ->formValidate( { post => 'bug_type', enum => $s->{types} }, { post => 'bug_status', enum => $s->{statusses} }, @@ -250,7 +272,7 @@ sub handleForm { $f = { %$f, %$fa }; return($f, $l) if $f->{_err}; } else { - push @{$f->{_err}}, [ 'bug_code', 'invalid', '' ] and return($f, undef) if $f->{bug_code} && $f->{bug_code} ne 'code'; + push @{$f->{_err}}, [ 'bug_code', 'invalid', '' ] and return($f, undef) if $f->{bug_code}; $f->{bug_type} = $l->{type}; $f->{bug_status} = $l->{status}; $f->{bug_closed} = $l->{closed}; @@ -266,18 +288,20 @@ sub handleForm { } # No errors? Save! - my $id = $s->dbSave(map $f->{"bug_$_"}, qw|id closed summary email type status message|); + my $id = $s->dbSave(map($f->{"bug_$_"}, qw|id closed summary name email type status message|), $admin); + + my $u = $url->($id); # For replies, send out notification emails if($l) { my $mails = $s->dbEmails($id); - my $u = $url->($id); + my $base = $TUWF::OBJ->reqBaseURI(); for(grep $_ ne $f->{bug_email}, @$mails) { $TUWF::OBJ->mail( "Hello!\n\n". "A new reply has been posted to an bug you have previously shown\n". "an interest in. You can view the reply at the following URL:\n". - " $u\n\n". + " $base$u\n\n". "If you do not wish to receive any more notifications for this (and\n". "perhaps other) bugs, please reply to this email stating your intent.", Subject => "Reply to $f->{bug_summary}", @@ -287,6 +311,8 @@ sub handleForm { } $l = $s->dbListing(id => $id)->[0] if !$l; + $TUWF::OBJ->resRedirect($u, 'post'); + $f->{$_} and $TUWF::OBJ->resCookie($_ => $f->{$_}, expires => time()+365*24*3600) for ('bug_name', 'bug_email', 'bug_code'); return($f, $l); } diff --git a/index.cgi b/index.cgi index 7978e2c..0260c83 100755 --- a/index.cgi +++ b/index.cgi @@ -96,6 +96,7 @@ TUWF::set( mail_from => 'Yorhels Bug Tracker ', # this is a fairly static site, allow some aggressive caching pre_request_handler => sub { $_[0]->resHeader('Cache-Control', 's-max-age=86400, max-age=3600'); 1; }, + cookie_defaults => { domain => 'dev.yorhel.nl', path => '/' }, ); TUWF::run(); @@ -245,7 +246,7 @@ sub bug_post { my($s, $p) = @_; return $s->resNotFound if $s->reqMethod() ne 'POST'; my $is = _bug_init($s, $p); - my($f, $l) = $is->handleForm(sub { "http://dev.yorhel.nl/$p/bug/".shift }); + my($f, $l) = $is->handleForm(sub { "/$p/bug/".shift }); if($f->{_err}) { $s->htmlHeader(title => 'Error creating message', page => $p, sec => 'bug'); @@ -279,8 +280,6 @@ sub bug_post { }); $done->recv; } - - $s->resRedirect("/$p/bug/$l->{issue}", 'post'); } diff --git a/style.css b/style.css index 3e40a7b..bc2d8f2 100644 --- a/style.css +++ b/style.css @@ -74,6 +74,7 @@ table thead td { font-weight: bold } .bug_item h1 { margin-top: 30px } .bug_item dt { clear: left; float: left; font-weight: bold; width: 60px } .bug_item dd { float: left; padding-right: 20px } +.bug_item dd b { color: #a20 } .bug_item p { clear: left; padding-top: 5px } .bug_frm fieldset { border: 0; margin-top: 40px } .bug_frm legend { font-size: 19px; color: #000; }