]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/comments.pm
comments: If comment content checks fail, store the comment (in .ikiwiki/comments_pen...
[ikiwiki.git] / IkiWiki / Plugin / comments.pm
index 644ef1be8ceec33a7185ff8dd3492962bdabe9d6..4d225b90ae88b40524b51858edcc9366efd99c01 100644 (file)
@@ -7,7 +7,7 @@ package IkiWiki::Plugin::comments;
 
 use warnings;
 use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
 use Encode;
 use POSIX qw(strftime);
 
@@ -198,8 +198,17 @@ sub preprocess {
                        $pagestate{$page}{meta}{author} = $params{claimedauthor};
                }
 
-               if (defined $params{url} and safeurl($params{url})) {
-                       $pagestate{$page}{meta}{authorurl} = $params{url};
+               if (defined $params{url}) {
+                       my $url=$params{url};
+
+                       eval q{use URI::Heuristic}; 
+                       if (! $@) {
+                               $url=URI::Heuristic::uf_uristr($url);
+                       }
+
+                       if (safeurl($url)) {
+                               $pagestate{$page}{meta}{authorurl} = $url;
+                       }
                }
        }
        else {
@@ -334,8 +343,6 @@ sub sessioncgi ($$) {
                error(gettext("bad page name"));
        }
 
-       # FIXME: is this right? Or should we be using the candidate subpage
-       # (whatever that might mean) as the base URL?
        my $baseurl = urlto($page, undef, 1);
 
        $form->title(sprintf(gettext("commenting on %s"),
@@ -373,14 +380,7 @@ sub sessioncgi ($$) {
        IkiWiki::check_canedit($page, $cgi, $session);
        $postcomment=0;
 
-       # FIXME: rather a simplistic way to make the comments...
-       my $i = 0;
-       my $file;
-       my $location;
-       do {
-               $i++;
-               $location = "$page/$config{comments_pagename}$i";
-       } while (-e "$config{srcdir}/$location._comment");
+       my $location=unique_comment_location($page, $config{srcdir});
 
        my $content = "[[!_comment format=$type\n";
 
@@ -399,19 +399,19 @@ sub sessioncgi ($$) {
 
        if ($config{comments_allowauthor}) {
                my $author = $form->field('author');
-               if (length $author) {
+               if (defined $author && length $author) {
                        $author =~ s/"/"/g;
                        $content .= " claimedauthor=\"$author\"\n";
                }
                my $url = $form->field('url');
-               if (length $url) {
+               if (defined $url && length $url) {
                        $url =~ s/"/"/g;
                        $content .= " url=\"$url\"\n";
                }
        }
 
        my $subject = $form->field('subject');
-       if (length $subject) {
+       if (defined $subject && length $subject) {
                $subject =~ s/"/"/g;
                $content .= " subject=\"$subject\"\n";
        }
@@ -432,8 +432,8 @@ sub sessioncgi ($$) {
 
        if ($form->submitted eq PREVIEW) {
                my $preview = IkiWiki::htmlize($location, $page, '_comment',
-                               IkiWiki::linkify($page, $page,
-                                       IkiWiki::preprocess($page, $page,
+                               IkiWiki::linkify($location, $page,
+                                       IkiWiki::preprocess($location, $page,
                                                IkiWiki::filter($location,
                                                        $page, $content),
                                                0, 1)));
@@ -447,6 +447,12 @@ sub sessioncgi ($$) {
                $template->param(title => $form->field('subject'));
                $template->param(ctime => displaytime(time));
 
+               IkiWiki::run_hooks(pagetemplate => sub {
+                       shift->(page => $location,
+                               destpage => $page,
+                               template => $template);
+               });
+
                $form->tmpl_param(page_preview => $template->output);
        }
        else {
@@ -454,12 +460,36 @@ sub sessioncgi ($$) {
        }
 
        if ($form->submitted eq POST_COMMENT && $form->validate) {
-               my $file = "$location._comment";
-
                IkiWiki::checksessionexpiry($cgi, $session);
+               
+               $postcomment=1;
+               my $ok=IkiWiki::check_content(content => $form->field('editcontent'),
+                       subject => $form->field('subject'),
+                       $config{comments_allowauthor} ? (
+                               author => $form->field('author'),
+                               url => $form->field('url'),
+                       ) : (),
+                       page => $location,
+                       cgi => $cgi,
+                       session => $session,
+                       nonfatal => 1,
+               );
+               $postcomment=0;
+
+               if (! $ok) {
+                       my $penddir=$config{wikistatedir}."/comments_pending";
+                       $location=unique_comment_location($page, $penddir);
+                       writefile("$location._comment", $penddir, $content);
+                       print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")),
+                               "<p>".
+                               gettext("Your comment will be posted after moderator review"),
+                               "</p>");
+                       exit;
+               }
 
                # FIXME: could probably do some sort of graceful retry
                # on error? Would require significant unwinding though
+               my $file = "$location._comment";
                writefile($file, $config{srcdir}, $content);
 
                my $conflict;
@@ -491,7 +521,10 @@ sub sessioncgi ($$) {
                error($conflict) if defined $conflict;
 
                # Jump to the new comment on the page.
-               IkiWiki::redirect($cgi, urlto($page, undef, 1)."#$location");
+               # The trailing question mark tries to avoid broken
+               # caches and get the most recent version of the page.
+               IkiWiki::redirect($cgi, urlto($page, undef, 1)."?updated#$location");
+
        }
        else {
                IkiWiki::showform ($form, \@buttons, $session, $cgi,
@@ -525,6 +558,8 @@ sub pagetemplate (@) {
        my $page = $params{page};
        my $template = $params{template};
        my $shown = ($template->query(name => 'commentslink') ||
+                    $template->query(name => 'commentsurl') ||
+                    $template->query(name => 'atomcommentsurl') ||
                     $template->query(name => 'comments')) &&
                    commentsshown($page);
 
@@ -554,6 +589,22 @@ sub pagetemplate (@) {
                }
        }
 
+       if ($template->query(name => 'commentsurl')) {
+               if ($shown) {
+                       $template->param(commentsurl =>
+                               urlto($page, undef, 1).'#comments');
+               }
+       }
+
+       if ($template->query(name => 'atomcommentsurl') && $config{usedirs}) {
+               if ($shown) {
+                       # This will 404 until there are some comments, but I
+                       # think that's probably OK...
+                       $template->param(atomcommentsurl =>
+                               urlto($page, undef, 1).'comments.atom');
+               }
+       }
+
        if ($template->query(name => 'commentslink')) {
                # XXX Would be nice to say how many comments there are in
                # the link. But, to update the number, blog pages
@@ -568,6 +619,12 @@ sub pagetemplate (@) {
                }
        }
 
+       # everything below this point is only relevant to the comments
+       # themselves
+       if (!exists $commentstate{$page}) {
+               return;
+       }
+
        if ($template->query(name => 'commentuser')) {
                $template->param(commentuser =>
                        $commentstate{$page}{commentuser});
@@ -592,6 +649,28 @@ sub pagetemplate (@) {
                $template->param(commentauthorurl =>
                        $commentstate{$page}{commentauthorurl});
        }
+
+       if ($template->query(name => 'removeurl') &&
+           IkiWiki::Plugin::remove->can("check_canremove") &&
+           length $config{cgiurl}) {
+               $template->param(removeurl => IkiWiki::cgiurl(do => 'remove',
+                       page => $page));
+               $template->param(have_actions => 1);
+       }
+}
+
+sub unique_comment_location ($) {
+       my $page=shift;
+       my $dir=shift;
+
+       my $location;
+       my $i = 0;
+       do {
+               $i++;
+               $location = "$page/$config{comments_pagename}$i";
+       } while (-e "$dir/$location._comment");
+
+       return $location;
 }
 
 package IkiWiki::PageSpec;