+}
+
+sub commentmoderation ($$) {
+ my $cgi=shift;
+ my $session=shift;
+
+ IkiWiki::needsignin($cgi, $session);
+ if (! IkiWiki::is_admin($session->param("name"))) {
+ error(gettext("you are not logged in as an admin"));
+ }
+
+ IkiWiki::decode_cgi_utf8($cgi);
+
+ if (defined $cgi->param('sid')) {
+ IkiWiki::checksessionexpiry($cgi, $session);
+
+ my $rejectalldefer=$cgi->param('rejectalldefer');
+
+ my %vars=$cgi->Vars;
+ my $added=0;
+ foreach my $id (keys %vars) {
+ if ($id =~ /(.*)\Q._comment\E$/) {
+ 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}/;
+ if (! defined $f || ! length $f ||
+ IkiWiki::file_pruned($f, $config{srcdir})) {
+ error("illegal file");
+ }
+
+ my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1));
+ my $file="$config{wikistatedir}/comments_pending/".
+ IkiWiki::possibly_foolish_untaint($id);
+
+ if ($action eq 'Accept') {
+ my $content=eval { readfile($file) };
+ next if $@; # file vanished since form was displayed
+ my $dest=unique_comment_location($page, $config{srcdir})."._comment";
+ writefile($dest, $config{srcdir}, $content);
+ if ($config{rcs} and $config{comments_commit}) {
+ IkiWiki::rcs_add($dest);
+ }
+ $added++;
+ }
+
+ # This removes empty subdirs, so the
+ # .ikiwiki/comments_pending dir will
+ # go away when all are moderated.
+ require IkiWiki::Render;
+ IkiWiki::prune($file);
+ }
+ }
+
+ if ($added) {
+ my $conflict;
+ if ($config{rcs} and $config{comments_commit}) {
+ my $message = gettext("Comment moderation");
+ IkiWiki::disable_commit_hook();
+ $conflict=IkiWiki::rcs_commit_staged($message,
+ $session->param('name'), $ENV{REMOTE_ADDR});
+ IkiWiki::enable_commit_hook();
+ IkiWiki::rcs_update();
+ }
+
+ # Now we need a refresh
+ require IkiWiki::Render;
+ IkiWiki::refresh();
+ IkiWiki::saveindex();
+
+ error($conflict) if defined $conflict;
+ }
+ }
+
+ my @comments=map {
+ my ($id, $ctime)=@{$_};
+ my $file="$config{wikistatedir}/comments_pending/$id";
+ my $content=readfile($file);
+ my $preview=previewcomment($content, $id,
+ IkiWiki::dirname($_), $ctime);
+ {
+ id => $id,
+ view => $preview,
+ }
+ } sort { $b->[1] <=> $a->[1] } comments_pending();
+
+ my $template=template("commentmoderation.tmpl");
+ $template->param(
+ sid => $session->id,
+ comments => \@comments,
+ );
+ IkiWiki::printheader($session);
+ my $out=$template->output;
+ IkiWiki::run_hooks(format => sub {
+ $out = shift->(page => "", content => $out);
+ });
+ print IkiWiki::misctemplate(gettext("comment moderation"), $out);
+ exit;
+}
+
+sub formbuilder_setup (@) {
+ my %params=@_;