]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - IkiWiki/Plugin/remove.pm
91f133ab69ee58ad29d2a5f48ba3cdc190a8a546
[git.ikiwiki.info.git] / IkiWiki / Plugin / remove.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::remove;
4 use warnings;
5 use strict;
6 use IkiWiki 2.00;
8 sub import { #{{{
9         hook(type => "formbuilder_setup", id => "remove", call => \&formbuilder_setup);
10         hook(type => "formbuilder", id => "remove", call => \&formbuilder);
11         hook(type => "sessioncgi", id => "remove", call => \&sessioncgi);
13 } # }}}
15 sub formbuilder_setup (@) { #{{{
16         my %params=@_;
17         my $form=$params{form};
18         my $q=$params{cgi};
20         if (defined $form->field("do") && $form->field("do") eq "edit") {
21                 # Removal button for the page, and also for attachments.
22                 push @{$params{buttons}}, "Remove";
23                 $form->tmpl_param("field-remove" => '<input name="_submit" type="submit" value="Remove Attachments" />');
24         }
25 } #}}}
27 sub confirmation_form ($$) { #{{{ 
28         my $q=shift;
29         my $session=shift;
31         eval q{use CGI::FormBuilder};
32         error($@) if $@;
33         my @fields=qw(do page);
34         my $f = CGI::FormBuilder->new(
35                 name => "remove",
36                 header => 0,
37                 charset => "utf-8",
38                 method => 'POST',
39                 javascript => 0,
40                 params => $q,
41                 action => $config{cgiurl},
42                 stylesheet => IkiWiki::baseurl()."style.css",
43                 fields => \@fields,
44         );
45         
46         $f->field(name => "do", type => "hidden", value => "remove", force => 1);
48         return $f, ["Remove", "Cancel"];
49 } #}}}
51 sub removal_confirm ($$@) {
52         my $q=shift;
53         my $session=shift;
54         my $attachment=shift;
55         my @pages=@_;
57         # Save current form state to allow returning to it later
58         # without losing any edits.
59         # (But don't save what button was submitted, to avoid
60         # looping back to here.)
61         # Note: "_submit" is CGI::FormBuilder internals.
62         $q->param(-name => "_submit", -value => "");
63         $session->param(postremove => scalar $q->Vars);
64         IkiWiki::cgi_savesession($session);
65         
66         my ($f, $buttons)=confirmation_form($q, $session);
67         $f->title(sprintf(gettext("confirm removal of %s"),
68                 join(", ", map { IkiWiki::pagetitle($_) } @pages)));
69         $f->field(name => "page", type => "hidden", value => \@pages, force => 1);
70         if (defined $attachment) {
71                 $f->field(name => "attachment", type => "hidden",
72                         value => $attachment, force => 1);
73         }
75         IkiWiki::showform($f, $buttons, $session, $q);
76         exit 0;
77 }
79 sub postremove ($) {
80         my $session=shift;
82         # Load saved form state and return to edit form.
83         my $postremove=CGI->new($session->param("postremove"));
84         $session->clear("postremove");
85         IkiWiki::cgi_savesession($session);
86         IkiWiki::cgi($postremove, $session);
87 }
89 sub formbuilder (@) { #{{{
90         my %params=@_;
91         my $form=$params{form};
93         if (defined $form->field("do") && $form->field("do") eq "edit") {
94                 my $q=$params{cgi};
95                 my $session=$params{session};
97                 if ($form->submitted eq "Remove") {
98                         removal_confirm($q, $session, 0, $form->field("page"));
99                 }
100                 elsif ($form->submitted eq "Remove Attachments") {
101                         removal_confirm($q, $session, 1, $q->param("attachment_select"));
102                 }
103         }
104 } #}}}
106 sub sessioncgi ($$) { #{{{
107         my $q=shift;
109         if ($q->param("do") eq 'remove') {
110                 my $session=shift;
111                 my ($form, $buttons)=confirmation_form($q, $session);
112                 IkiWiki::decode_form_utf8($form);
114                 if ($form->submitted eq 'Cancel') {
115                         postremove($session);
116                 }
117                 elsif ($form->submitted eq 'Remove' && $form->validate) {
118                         my @pages=$q->param("page");
119         
120                         # Validate removal by checking that the page exists,
121                         # and that the user is allowed to edit(/remove) it.
122                         my @files;
123                         foreach my $page (@pages) {
124                                 if (! exists $pagesources{$page}) {
125                                         error(sprintf(gettext("%s does not exist"),
126                                         htmllink("", "", $page, noimageinline => 1)));
127                                 }
128                                 IkiWiki::check_canedit($page, $q, $session);
130                                 my $file=$pagesources{$page};
131                                 if (! -e "$config{srcdir}/$file") {
132                                         error(sprintf(gettext("%s is not in the srcdir, so it cannot be deleted"), $file));
133                                 }
134                                 elsif (! -f "$config{srcdir}/$file") {
135                                         error(sprintf(gettext("%s is not a file"), $file));
136                                 }
138                                 # This untaint is safe because we've
139                                 # verified the file is a known source file,
140                                 # and is in the srcdir, and is a regular
141                                 # file.
142                                 push @files, IkiWiki::possibly_foolish_untaint($file);
143                         }
145                         # Do removal, and update the wiki.
146                         require IkiWiki::Render;
147                         if ($config{rcs}) {
148                                 IkiWiki::disable_commit_hook();
149                                 foreach my $file (@files) {
150                                         my $token=IkiWiki::rcs_prepedit($file);
151                                         IkiWiki::rcs_remove($file);
152                                         IkiWiki::rcs_commit($file, gettext("removed"),
153                                                 $token, $session->param("name"), $ENV{REMOTE_ADDR});
154                                 }
155                                 IkiWiki::enable_commit_hook();
156                                 IkiWiki::rcs_update();
157                         }
158                         else {
159                                 foreach my $file (@files) {
160                                         IkiWiki::prune("$config{srcdir}/$file");
161                                 }
162                         }
163                         IkiWiki::refresh();
164                         IkiWiki::saveindex();
166                         if ($q->param("attachment")) {
167                                 # Attachments were deleted, so redirect
168                                 # back to the edit form.
169                                 postremove($session);
170                         }
171                         else {
172                                 # The page is gone, so redirect to parent
173                                 # of the page.
174                                 my $parent=IkiWiki::dirname($pages[0]);
175                                 if (! exists $pagesources{$parent}) {
176                                         $parent="index";
177                                 }
178                                 IkiWiki::redirect($q, $config{url}."/".htmlpage($parent));
179                         }
180                 }
181                 else {
182                         IkiWiki::showform($form, $buttons, $session, $q);
183                 }
185                 exit 0;
186         }