Merge commit 'upstream/master' into prv/po
authorintrigeri <intrigeri@boum.org>
Sat, 17 Jan 2009 13:01:53 +0000 (14:01 +0100)
committerintrigeri <intrigeri@boum.org>
Sat, 17 Jan 2009 13:01:53 +0000 (14:01 +0100)
Conflicts:

IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/skeleton.pm.example
doc/plugins/write.mdwn
t/syntax.t

1  2 
IkiWiki/Plugin/editpage.pm
IkiWiki/Plugin/skeleton.pm.example
doc/plugins/write.mdwn
t/syntax.t

index 91d125a5ca1ca30e836706a6e5e2aa43df6eced2,bba52e4fd322e8bbad5f63a13198ff5f491cdef5..658d664af38d76b330ae9c27b74e77e5f28172a6
@@@ -78,36 -78,45 +78,72 @@@ sub check_canedit ($$$;$) 
                        }
                }
        });
-       return $canedit;
+       return defined $canedit ? $canedit : 1;
+ }
+ sub check_content (@) {
+       my %params=@_;
+       
+       return 1 if ! exists $hooks{checkcontent}; # optimisation
+       if (exists $pagesources{$params{page}}) {
+               my @diff;
+               my %old=map { $_ => 1 }
+                       split("\n", readfile(srcfile($pagesources{$params{page}})));
+               foreach my $line (split("\n", $params{content})) {
+                       push @diff, $line if ! exists $old{$_};
+               }
+               $params{content}=join("\n", @diff);
+       }
+       my $ok;
+       run_hooks(checkcontent => sub {
+               return if defined $ok;
+               my $ret=shift->(%params);
+               if (defined $ret) {
+                       if ($ret eq "") {
+                               $ok=1;
+                       }
+                       elsif (ref $ret eq 'CODE') {
+                               $ret->();
+                               $ok=0;
+                       }
+                       elsif (defined $ret) {
+                               error($ret);
+                       }
+               }
+       });
+       return defined $ok ? $ok : 1;
  }
  
 +sub check_cansave ($$$$) {
 +      my $page=shift;
 +      my $content=shift;
 +      my $q=shift;
 +      my $session=shift;
 +
 +      my $cansave;
 +      run_hooks(cansave => sub {
 +              return if defined $cansave;
 +              my $ret=shift->($page, $content, $q, $session);
 +              if (defined $ret) {
 +                      if ($ret eq "") {
 +                              $cansave=1;
 +                      }
 +                      elsif (ref $ret eq 'CODE') {
 +                              $ret->();
 +                              $cansave=0;
 +                      }
 +                      else {
 +                              error($ret);
 +                              $cansave=0;
 +                      }
 +              }
 +      });
 +      return $cansave;
 +}
 +
  sub cgi_editpage ($$) {
        my $q=shift;
        my $session=shift;
                        showform($form, \@buttons, $session, $q, forcebaseurl => $baseurl);
                        exit;
                }
+                       
+               my $message="";
+               if (defined $form->field('comments') &&
+                   length $form->field('comments')) {
+                       $message=$form->field('comments');
+               }
                
                my $content=$form->field('editcontent');
 +              check_cansave($page, $content, $q, $session);
+               check_content(content => $content, page => $page,
+                       cgi => $q, session => $session,
+                       subject => $message);
                run_hooks(editcontent => sub {
                        $content=shift->(
                                content => $content,
index 0bd5edeef748b328cfd869c2104860a1c0b6794f,ea7d6e47f576b3cb04ffeb79d9471fdab1cfa9b1..30c8dbd5c82d06dde62bc7a219fbcbf77bd64177
@@@ -30,7 -30,7 +30,8 @@@ sub import 
        hook(type => "auth", id => "skeleton", call => \&auth);
        hook(type => "sessioncgi", id => "skeleton", call => \&sessioncgi);
        hook(type => "canedit", id => "skeleton", call => \&canedit);
 +      hook(type => "cansave", id => "skeleton", call => \&cansave);
+       hook(type => "checkcontent", id => "skeleton", call => \&checkcontent);
        hook(type => "editcontent", id => "skeleton", call => \&editcontent);
        hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "skeleton", call => \&formbuilder);
@@@ -181,29 -181,10 +182,36 @@@ sub canedit ($$$) 
        debug("skeleton plugin running in canedit");
  }
  
++<<<<<<< HEAD:IkiWiki/Plugin/skeleton.pm.example
 +sub cansave ($$$$) {
 +      my $page=shift;
 +      my $content=shift;
 +      my $cgi=shift;
 +      my $session=shift;
 +
 +      debug("skeleton plugin running in cansave");
 +}
 +
 +sub canremove ($$$) {
 +      my $page=shift;
 +      my $cgi=shift;
 +      my $session=shift;
 +
 +      debug("skeleton plugin running in canremove");
 +}
 +
 +sub canrename ($$$) {
 +      my $page=shift;
 +      my $cgi=shift;
 +      my $session=shift;
 +
 +      debug("skeleton plugin running in canrename");
++=======
+ sub checkcontent (@) {
+       my %params=@_;
+       debug("skeleton plugin running in checkcontent");
++>>>>>>> upstream/master:IkiWiki/Plugin/skeleton.pm.example
  }
  
  sub editcontent ($$$) {
index 4db02b532557addd28922fcf4c26ce1eda458586,99eea3d1696b3240647b439edae4d8768ddf1033..ef14f18dbb13fe81b0f85d1fcb2e85fd6fa63db1
@@@ -321,41 -321,26 +321,61 @@@ This hook should avoid directly redirec
  since it's sometimes used to test to see which pages in a set of pages a
  user can edit.
  
 +### cansave
 +
 +      hook(type => "cansave", id => "foo", call => \&cansave);
 +
 +This hook can be used to implement arbitrary access methods to control
 +when a page being edited can be saved using the web interface (commits
 +from revision control bypass it).
 +
 +When a page is about to be saved, each registered cansave hook is
 +called in turn, and passed the page name, the edited content, a CGI
 +object and a session object.
 +
 +The return value of a cansave hook is interpreted the same as for the
 +canedit hook.
 +
 +### canremove
 +
 +      hook(type => "canremove", id => "foo", call => \&canremove);
 +
 +This hook can be used to implement arbitrary access methods to control when
 +a page can be removed using the web interface (commits from revision control
 +bypass it). It works exactly like the `canedit` hook.
 +
 +### canrename
 +
 +      hook(type => "canrename", id => "foo", call => \&canrename);
 +
 +This hook can be used to implement arbitrary access methods to control when
 +a page can be renamed using the web interface (commits from revision control
 +bypass it). It works exactly like the `canedit` and `canremove` hook,
 +but is passed:
 +* a CGI object
 +* a session object
 +* the named parameters `src`, `srcfile`, `dest` and `destfile`.
 +
+ ### checkcontent
+       
+       hook(type => "checkcontent", id => "foo", call => \&checkcontent);
+ This hook is called to check the content a user has entered on a page,
+ before it is saved, and decide if it should be allowed.
+ It is passed named parameters: `content`, `page`, `cgi`, and `session`. If
+ the content the user has entered is a comment, it may also be passed some
+ additional parameters: `author`, `url`, and `subject`. The `subject`
+ parameter may also be filled with the user's comment about the change.
+ Note: When the user edits an existing wiki page, the passed `content` will
+ include only the lines that they added to the page, or modified.
+ The hook should return `undef` on success. If the content is disallowed, it
+ should return a message stating what the problem is, or a function
+ that can be run to perform whatever action is necessary to allow the user
+ to post the content.
  ### editcontent
  
        hook(type => "editcontent", id => "foo", call => \&editcontent);
diff --cc t/syntax.t
index 8c96d1d848014e9145739515e974f0b5aac271ac,9d5cbc3739d168b9362cbfb91620a9f624e3a918..ddb0da073c9c4dddd7389f4d7cabc2b29a8fa948
@@@ -5,8 -5,8 +5,8 @@@ use Test::More
  
  my @progs="ikiwiki.in";
  my @libs="IkiWiki.pm";
- # monotone, external, amazon_s3 skipped since they need perl modules
- push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v amazon_s3.pm | grep -v po.pm`;
 -# monotone, external, blogspam, amazon_s3 skipped since they need perl modules
 -push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v blogspam.pm | grep -v amazon_s3.pm`;
++# monotone, external, blogspam, amazon_s3, po skipped since they need perl modules
++push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v blogspam.pm | grep -v amazon_s3.pm | grep -v po.pm`;
  push @libs, 'IkiWiki/Plugin/skeleton.pm.example';
  
  plan(tests => (@progs + @libs));