hook(type => "formbuilder_setup", id => "rename", call => \&formbuilder_setup);
hook(type => "formbuilder", id => "rename", call => \&formbuilder);
hook(type => "sessioncgi", id => "rename", call => \&sessioncgi);
-
+ hook(type => "rename", id => "rename", call => \&rename_subpages);
}
sub getsetup () {
plugin => {
safe => 1,
rebuild => 0,
+ section => "web",
},
}
IkiWiki::check_canedit($src, $q, $session);
if ($attachment) {
if (IkiWiki::Plugin::attachment->can("check_canattach")) {
- IkiWiki::Plugin::attachment::check_canattach($session, $src, $srcfile);
+ IkiWiki::Plugin::attachment::check_canattach($session, $src, "$config{srcdir}/$srcfile");
}
else {
error("renaming of attachments is not allowed");
error(gettext("no change to the file name was specified"));
}
- # Must be a legal filename, and not absolute.
- if (IkiWiki::file_pruned($destfile, $config{srcdir}) ||
- $destfile=~/^\//) {
+ # Must be a legal filename.
+ if (IkiWiki::file_pruned($destfile)) {
error(sprintf(gettext("illegal name")));
}
if ($attachment) {
# Note that $srcfile is used here, not $destfile,
# because it wants the current file, to check it.
- IkiWiki::Plugin::attachment::check_canattach($session, $dest, $srcfile);
+ IkiWiki::Plugin::attachment::check_canattach($session, $dest, "$config{srcdir}/$srcfile");
}
}
my $canrename;
IkiWiki::run_hooks(canrename => sub {
return if defined $canrename;
- my $ret=shift->($src, $q, $session);
+ my $ret=shift->(cgi => $q, session => $session,
+ src => $src, srcfile => $srcfile,
+ dest => $dest, destfile => $destfile);
if (defined $ret) {
if ($ret eq "") {
$canrename=1;
}
}
});
- return $canrename;
}
sub rename_form ($$$) {
javascript => 0,
params => $q,
action => $config{cgiurl},
- stylesheet => IkiWiki::baseurl()."style.css",
+ stylesheet => 1,
fields => [qw{do page new_name attachment}],
);
$f->field(name => "do", type => "hidden", value => "rename", force => 1);
+ $f->field(name => "sid", type => "hidden", value => $session->id,
+ force => 1);
$f->field(name => "page", type => "hidden", value => $page, force => 1);
$f->field(name => "new_name", value => pagetitle($page, 1), size => 60);
if (!$q->param("attachment")) {
# insert the standard extensions
my @page_types;
if (exists $IkiWiki::hooks{htmlize}) {
- @page_types=grep { !/^_/ }
- keys %{$IkiWiki::hooks{htmlize}};
+ foreach my $key (grep { !/^_/ } keys %{$IkiWiki::hooks{htmlize}}) {
+ push @page_types, [$key, $IkiWiki::hooks{htmlize}{$key}{longname} || $key];
+ }
}
+ @page_types=sort @page_types;
# make sure the current extension is in the list
my ($ext) = $pagesources{$page}=~/\.([^.]+)$/;
if (! $IkiWiki::hooks{htmlize}{$ext}) {
- unshift(@page_types, $ext);
+ unshift(@page_types, [$ext, $ext]);
}
$f->field(name => "type", type => 'select',
# Update edit form content to fix any links present
# on it.
$postrename->param("editcontent",
- renamelink_hook($dest, $src, $dest,
+ renamepage_hook($dest, $src, $dest,
$postrename->param("editcontent")));
# Get a new edit token; old was likely invalidated.
if (defined $form->field("do") && ($form->field("do") eq "edit" ||
$form->field("do") eq "create")) {
+ IkiWiki::decode_form_utf8($form);
my $q=$params{cgi};
my $session=$params{session};
rename_start($q, $session, 0, $form->field("page"));
}
elsif ($form->submitted eq "Rename Attachment") {
- my @selected=$q->param("attachment_select");
+ my @selected=map { Encode::decode_utf8($_) } $q->param("attachment_select");
if (@selected > 1) {
error(gettext("Only one attachment can be renamed at a time."));
}
if ($q->param("do") eq 'rename') {
my $session=shift;
- my ($form, $buttons)=rename_form($q, $session, $q->param("page"));
+ my ($form, $buttons)=rename_form($q, $session, Encode::decode_utf8($q->param("page")));
IkiWiki::decode_form_utf8($form);
if ($form->submitted eq 'Cancel') {
postrename($session);
}
elsif ($form->submitted eq 'Rename' && $form->validate) {
+ IkiWiki::checksessionexpiry($q, $session, $q->param('sid'));
+
# Queue of rename actions to perfom.
my @torename;
# These untaints are safe because of the checks
# performed in check_canrename later.
- my $src=$q->param("page");
+ my $src=$form->field("page");
my $srcfile=IkiWiki::possibly_foolish_untaint($pagesources{$src});
- my $dest=IkiWiki::possibly_foolish_untaint(titlepage($q->param("new_name")));
+ my $dest=IkiWiki::possibly_foolish_untaint(titlepage($form->field("new_name")));
my $destfile=$dest;
if (! $q->param("attachment")) {
my $type=$q->param('type');
required => 1,
};
- IkiWiki::run_hooks(rename => sub { shift->(\@torename, $q, $session); });
-
- # See if any subpages need to be renamed.
- if ($q->param("subpages") && $src ne $dest) {
- foreach my $p (keys %pagesources) {
- next unless $pagesources{$p}=~m/^\Q$src\E\//;
- # If indexpages is enabled, the
- # srcfile should not be confused
- # with a subpage.
- next if $pagesources{$p} eq $srcfile;
-
- my $d=$pagesources{$p};
- $d=~s/^\Q$src\E\//$dest\//;
- push @torename, {
- src => $p,
- srcfile => $pagesources{$p},
- dest => pagename($d),
- destfile => $d,
- required => 0,
- };
- }
- }
-
+ @torename=rename_hook(
+ torename => \@torename,
+ done => {},
+ cgi => $q,
+ session => $session,
+ );
+
require IkiWiki::Render;
IkiWiki::disable_commit_hook() if $config{rcs};
my %origpagesources=%pagesources;
$pagesources{$rename->{src}}=$rename->{destfile};
}
IkiWiki::rcs_commit_staged(
- sprintf(gettext("rename %s to %s"), $srcfile, $destfile),
- $session->param("name"), $ENV{REMOTE_ADDR}) if $config{rcs};
+ message => sprintf(gettext("rename %s to %s"), $srcfile, $destfile),
+ session => $session,
+ ) if $config{rcs};
# Then link fixups.
foreach my $rename (@torename) {
$template->param(error => $rename->{error});
if ($rename->{src} ne $rename->{dest}) {
$template->param(brokenlinks_checked => 1);
- $template->param(brokenlinks => [
- map {
- {
- page => htmllink($rename->{dest}, $rename->{dest}, $_,
- noimageinline => 1)
- }
- } @{$rename->{brokenlinks}}
- ]);
- $template->param(fixedlinks => [
- map {
- {
- page => htmllink($rename->{dest}, $rename->{dest}, $_,
- noimageinline => 1)
- }
- } @{$rename->{fixedlinks}}
- ]);
+ $template->param(brokenlinks => linklist($rename->{dest}, $rename->{brokenlinks}));
+ $template->param(fixedlinks => linklist($rename->{dest}, $rename->{fixedlinks}));
}
$renamesummary.=$template->output;
}
}
}
-sub renamelink_hook ($$$$) {
+# Add subpages to the list of pages to be renamed, if needed.
+sub rename_subpages (@) {
+ my %params = @_;
+
+ my %torename = %{$params{torename}};
+ my $q = $params{cgi};
+ my $src = $torename{src};
+ my $srcfile = $torename{src};
+ my $dest = $torename{dest};
+ my $destfile = $torename{dest};
+
+ return () unless ($q->param("subpages") && $src ne $dest);
+
+ my @ret;
+ foreach my $p (keys %pagesources) {
+ next unless $pagesources{$p}=~m/^\Q$src\E\//;
+ # If indexpages is enabled, the srcfile should not be confused
+ # with a subpage.
+ next if $pagesources{$p} eq $srcfile;
+
+ my $d=$pagesources{$p};
+ $d=~s/^\Q$src\E\//$dest\//;
+ push @ret, {
+ src => $p,
+ srcfile => $pagesources{$p},
+ dest => pagename($d),
+ destfile => $d,
+ required => 0,
+ };
+ }
+ return @ret;
+}
+
+sub linklist {
+ # generates a list of links in a form suitable for FormBuilder
+ my $dest=shift;
+ my $list=shift;
+ # converts a list of pages into a list of links
+ # in a form suitable for FormBuilder.
+
+ [map {
+ {
+ page => htmllink($dest, $dest, $_,
+ noimageinline => 1,
+ linktext => pagetitle($_),
+ )
+ }
+ } @{$list}]
+}
+
+sub renamepage_hook ($$$$) {
my ($page, $src, $dest, $content)=@_;
- IkiWiki::run_hooks(renamelink => sub {
+ IkiWiki::run_hooks(renamepage => sub {
$content=shift->(
page => $page,
oldpage => $src,
return $content;
}
-
+
+sub rename_hook {
+ my %params = @_;
+
+ my @torename=@{$params{torename}};
+ my %done=%{$params{done}};
+ my $q=$params{cgi};
+ my $session=$params{session};
+
+ return () unless @torename;
+
+ my @nextset;
+ foreach my $torename (@torename) {
+ unless (exists $done{$torename->{src}} && $done{$torename->{src}}) {
+ IkiWiki::run_hooks(rename => sub {
+ push @nextset, shift->(
+ torename => $torename,
+ cgi => $q,
+ session => $session,
+ );
+ });
+ $done{$torename->{src}}=1;
+ }
+ }
+
+ push @torename, rename_hook(
+ torename => \@nextset,
+ done => \%done,
+ cgi => $q,
+ session => $session,
+ );
+
+ # dedup
+ my %seen;
+ return grep { ! $seen{$_->{src}}++ } @torename;
+}
+
sub do_rename ($$$) {
my $rename=shift;
my $q=shift;
if ($needfix) {
my $file=$pagesources{$page};
my $oldcontent=readfile($config{srcdir}."/".$file);
- my $content=renamelink_hook($page, $rename->{src}, $rename->{dest}, $oldcontent);
+ my $content=renamepage_hook($page, $rename->{src}, $rename->{dest}, $oldcontent);
if ($oldcontent ne $content) {
my $token=IkiWiki::rcs_prepedit($file);
eval { writefile($file, $config{srcdir}, $content) };
$file,
sprintf(gettext("update for rename of %s to %s"), $rename->{srcfile}, $rename->{destfile}),
$token,
- $session->param("name"),
- $ENV{REMOTE_ADDR}
+ $session->param("name"),
+ $session->remote_addr(),
);
push @fixedlinks, $page if ! defined $conflict;
}