X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/ca33969823342c3c61219a2cb167e40f765f934b..8d3c89f0c75c31c5e17a661150662e3efd3a146e:/IkiWiki/Plugin/comments.pm diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 1c219b6c6..93c8c4061 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -26,8 +26,11 @@ sub import { hook(type => "preprocess", id => '_comment', call => \&preprocess); hook(type => "sessioncgi", id => 'comment', call => \&sessioncgi); hook(type => "htmlize", id => "_comment", call => \&htmlize); + hook(type => "htmlize", id => "_comment_pending", + call => \&htmlize_pending); hook(type => "pagetemplate", id => "comments", call => \&pagetemplate); - hook(type => "formbuilder_setup", id => "comments", call => \&formbuilder_setup); + hook(type => "formbuilder_setup", id => "comments", + call => \&formbuilder_setup); # Load goto to fix up user page links for logged-in commenters IkiWiki::loadplugin("goto"); IkiWiki::loadplugin("inline"); @@ -104,6 +107,14 @@ sub htmlize { return $params{content}; } +sub htmlize_pending { + my %params = @_; + return sprintf(gettext("comment pending %s"), + ''. + gettext("moderation").''); +} + # FIXME: copied verbatim from meta sub safeurl ($) { my $url=shift; @@ -274,7 +285,7 @@ sub editcomment ($$) { action => $config{cgiurl}, header => 0, table => 0, - template => scalar IkiWiki::template_params('editcomment.tmpl'), + template => { template('editcomment.tmpl') }, ); IkiWiki::decode_form_utf8($form); @@ -462,9 +473,15 @@ sub editcomment ($$) { $postcomment=0; if (! $ok) { - my $penddir=$config{wikistatedir}."/comments_pending"; - $location=unique_comment_location($page, $content, $penddir); - writefile("$location._comment", $penddir, $content); + $location=unique_comment_location($page, $content, $config{srcdir}); + writefile("$location._comment_pending", $config{srcdir}, $content); + + # Refresh so anything that deals with pending + # comments can be updated. + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + IkiWiki::printheader($session); print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")), "

". @@ -540,21 +557,24 @@ sub commentmoderation ($$) { my %vars=$cgi->Vars; my $added=0; foreach my $id (keys %vars) { - if ($id =~ /(.*)\Q._comment\E$/) { + if ($id =~ /(.*)\._comment(?:_pending)?$/) { my $action=$cgi->param($id); next if $action eq 'Defer' && ! $rejectalldefer; # Make sure that the id is of a legal - # pending comment before untainting. - my ($f)= $id =~ /$config{wiki_file_regexp}/; + # pending comment. + my ($f) = $id =~ /$config{wiki_file_regexp}/; if (! defined $f || ! length $f || IkiWiki::file_pruned($f)) { error("illegal file"); } - my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1)); - my $file="$config{wikistatedir}/comments_pending/". - IkiWiki::possibly_foolish_untaint($id); + my $page=IkiWiki::dirname($f); + my $file="$config{srcdir}/$f"; + if (! -e $file) { + # old location + $file="$config{wikistatedir}/comments_pending/".$f; + } if ($action eq 'Accept') { my $content=eval { readfile($file) }; @@ -567,9 +587,6 @@ sub commentmoderation ($$) { $added++; } - # This removes empty subdirs, so the - # .ikiwiki/comments_pending dir will - # go away when all are moderated. require IkiWiki::Render; IkiWiki::prune($file); } @@ -596,16 +613,15 @@ sub commentmoderation ($$) { } my @comments=map { - my ($id, $ctime)=@{$_}; - my $file="$config{wikistatedir}/comments_pending/$id"; - my $content=readfile($file); + my ($id, $dir, $ctime)=@{$_}; + my $content=readfile("$dir/$id"); my $preview=previewcomment($content, $id, - IkiWiki::dirname($_), $ctime); + $id, $ctime); { id => $id, view => $preview, - } - } sort { $b->[1] <=> $a->[1] } comments_pending(); + } + } sort { $b->[2] <=> $a->[2] } comments_pending(); my $template=template("commentmoderation.tmpl"); $template->param( @@ -635,30 +651,35 @@ sub formbuilder_setup (@) { } sub comments_pending () { - my $dir="$config{wikistatedir}/comments_pending/"; - return unless -d $dir; - my @ret; + eval q{use File::Find}; error($@) if $@; - find({ - no_chdir => 1, - wanted => sub { - $_=decode_utf8($_); - if (IkiWiki::file_pruned($_, $dir)) { - $File::Find::prune=1; - } - elsif (! -l $_ && ! -d _) { - $File::Find::prune=0; - my ($f)=/$config{wiki_file_regexp}/; # untaint - if (defined $f && $f =~ /\Q._comment\E$/) { - my $ctime=(stat($f))[10]; - $f=~s/^\Q$dir\E\/?//; - push @ret, [$f, $ctime]; + + my $find_comments=sub { + my $dir=shift; + my $extension=shift; + return unless -d $dir; + find({ + no_chdir => 1, + wanted => sub { + my $file=decode_utf8($_); + $file=~s/^\Q$dir\E\/?//; + return if ! length $file || IkiWiki::file_pruned($file) + || -l $_ || -d _ || $file !~ /\Q$extension\E$/; + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint + if (defined $f) { + my $ctime=(stat($_))[10]; + push @ret, [$f, $dir, $ctime]; } } - } - }, $dir); + }, $dir); + }; + + $find_comments->($config{srcdir}, "._comment_pending"); + # old location + $find_comments->("$config{wikistatedir}/comments_pending/", + "._comment"); return @ret; } @@ -676,7 +697,8 @@ sub previewcomment ($$$) { my $template = template("comment.tmpl"); $template->param(content => $preview); - $template->param(ctime => displaytime($time)); + $template->param(ctime => displaytime($time, undef, 1)); + $template->param(html5 => $config{html5}); IkiWiki::run_hooks(pagetemplate => sub { shift->(page => $location, @@ -692,7 +714,7 @@ sub previewcomment ($$$) { sub commentsshown ($) { my $page=shift; - return ! pagespec_match($page, "internal(*/$config{comments_pagename}*)", + return ! pagespec_match($page, "comment(*)", location => $page) && pagespec_match($page, $config{comments_pagespec}, location => $page); @@ -722,7 +744,7 @@ sub pagetemplate (@) { my $comments = undef; if ($shown) { $comments = IkiWiki::preprocess_inline( - pages => "internal($page/$config{comments_pagename}*)", + pages => "comment($page)", template => 'comment', show => 0, reverse => 'yes', @@ -850,7 +872,8 @@ sub unique_comment_location ($$$) { do { $i++; $location = "$page/$config{comments_pagename}${i}_${content_md5}"; - } while (-e "$dir/$location._comment"); + } while (-e "$dir/$location._comment" || + -e "$dir/$location._comment_pending"); return $location; } @@ -876,7 +899,35 @@ sub match_postcomment ($$;@) { if (! $postcomment) { return IkiWiki::FailReason->new("not posting a comment"); } - return match_glob($page, $glob); + return match_glob($page, $glob, @_); +} + +sub match_comment ($$;@) { + my $page = shift; + my $glob = shift; + + my $match=match_glob($page, "$glob/*", internal => 1, @_); + if ($match && exists $IkiWiki::pagesources{$page}) { + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if (defined $type && $type ne "_comment") { + return IkiWiki::FailReason->new("$page is not a comment"); + } + } + return $match; +} + +sub match_comment_pending ($$;@) { + my $page = shift; + my $glob = shift; + + my $match=match_glob($page, "$glob/*", internal => 1, @_); + if ($match && $IkiWiki::pagesources{$page}) { + my $type=IkiWiki::pagetype($IkiWiki::pagesources{$page}); + if (defined $type && $type ne "_comment_pending") { + return IkiWiki::FailReason->new("$page is not a pending comment"); + } + } + return $match; } 1