my $type=pagetype($file);
my $page=$file;
- $page=~s/\Q.$type\E*$//
+ $page=~s/\Q.$type\E*$//
if defined $type && !$hooks{htmlize}{$type}{keepextension}
&& !$hooks{htmlize}{$type}{noextension};
if ($config{indexpages} && $page=~/(.*)\/index$/) {
my $page=shift;
my $link=shift;
- return $page eq $link;
+ return $page eq $link;
}
sub htmllink ($$$;@) {
return defined $ok ? $ok : 1;
}
+sub check_canchange (@) {
+ my %params = @_;
+ my $cgi = $params{cgi};
+ my $session = $params{session};
+ my @changes = @{$params{changes}};
+
+ my %newfiles;
+ foreach my $change (@changes) {
+ # This untaint is safe because we check file_pruned and
+ # wiki_file_regexp.
+ my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
+ $file=possibly_foolish_untaint($file);
+ if (! defined $file || ! length $file ||
+ file_pruned($file)) {
+ error(gettext("bad file name %s"), $file);
+ }
+
+ my $type=pagetype($file);
+ my $page=pagename($file) if defined $type;
+
+ if ($change->{action} eq 'add') {
+ $newfiles{$file}=1;
+ }
+
+ if ($change->{action} eq 'change' ||
+ $change->{action} eq 'add') {
+ if (defined $page) {
+ check_canedit($page, $cgi, $session);
+ next;
+ }
+ else {
+ if (IkiWiki::Plugin::attachment->can("check_canattach")) {
+ IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path});
+ check_canedit($file, $cgi, $session);
+ next;
+ }
+ }
+ }
+ elsif ($change->{action} eq 'remove') {
+ # check_canremove tests to see if the file is present
+ # on disk. This will fail when a single commit adds a
+ # file and then removes it again. Avoid the problem
+ # by not testing the removal in such pairs of changes.
+ # (The add is still tested, just to make sure that
+ # no data is added to the repo that a web edit
+ # could not add.)
+ next if $newfiles{$file};
+
+ if (IkiWiki::Plugin::remove->can("check_canremove")) {
+ IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session);
+ check_canedit(defined $page ? $page : $file, $cgi, $session);
+ next;
+ }
+ }
+ else {
+ error "unknown action ".$change->{action};
+ }
+
+ error sprintf(gettext("you are not allowed to change %s"), $file);
+ }
+}
+
+
my $wikilock;
sub lockwiki () {
if (exists $index->{version} && ! ref $index->{version}) {
$pages=$index->{page};
%wikistate=%{$index->{state}};
+ # Handle plugins that got disabled by loading a new setup.
+ if (exists $config{setupfile}) {
+ require IkiWiki::Setup;
+ IkiWiki::Setup::disabled_plugins(
+ grep { ! $loaded_plugins{$_} } keys %wikistate);
+ }
}
else {
$pages=$index;
sub saveindex () {
run_hooks(savestate => sub { shift->() });
- my %hookids;
- foreach my $type (keys %hooks) {
- $hookids{$_}=1 foreach keys %{$hooks{$type}};
- }
- my @hookids=keys %hookids;
+ my @plugins=keys %loaded_plugins;
if (! -d $config{wikistatedir}) {
mkdir($config{wikistatedir});
}
if (exists $pagestate{$page}) {
- foreach my $id (@hookids) {
+ foreach my $id (@plugins) {
foreach my $key (keys %{$pagestate{$page}{$id}}) {
$index{page}{$src}{state}{$id}{$key}=$pagestate{$page}{$id}{$key};
}
}
$index{state}={};
- foreach my $id (@hookids) {
+ foreach my $id (@plugins) {
+ $index{state}{$id}={}; # used to detect disabled plugins
foreach my $key (keys %{$wikistate{$id}}) {
$index{state}{$id}{$key}=$wikistate{$id}{$key};
}
my $page=shift;
my ($filename, $tpage, $untrusted)=template_file($name);
+ if (! defined $filename) {
+ error(sprintf(gettext("template %s not found"), $name))
+ }
+
if (defined $page && defined $tpage) {
add_depends($page, $tpage);
}
-
- return unless defined $filename;
-
+
my @opts=(
filter => sub {
my $text_ref = shift;
my $path=shift;
my $from=shift;
- if ($path =~ m!^\./!) {
- $from=~s#/?[^/]+$## if defined $from;
- $path=~s#^\./##;
- $path="$from/$path" if defined $from && length $from;
+ if ($path =~ m!^\.(/|$)!) {
+ if ($1) {
+ $from=~s#/?[^/]+$## if defined $from;
+ $path=~s#^\./##;
+ $path="$from/$path" if defined $from && length $from;
+ }
+ else {
+ $path = $from;
+ $path = "" unless defined $path;
+ }
}
return $path;
sub match_page ($$;@) {
my $page=shift;
my $match=match_glob($page, shift, @_);
- if ($match && ! (exists $IkiWiki::pagesources{$page}
- && defined IkiWiki::pagetype($IkiWiki::pagesources{$page}))) {
- return IkiWiki::FailReason->new("$page is not a page");
- }
- else {
- return $match;
+ if ($match) {
+ my $source=exists $IkiWiki::pagesources{$page} ?
+ $IkiWiki::pagesources{$page} :
+ $IkiWiki::delpagesources{$page};
+ my $type=defined $source ? IkiWiki::pagetype($source) : undef;
+ if (! defined $type) {
+ return IkiWiki::FailReason->new("$page is not a page");
+ }
}
+ return $match;
}
sub match_link ($$;@) {