0.12_12 commit r0_12_12
authorTony Cook <tony@develop-help.com>
Tue, 3 Sep 2002 03:28:00 +0000 (03:28 +0000)
committertony <tony@45cb6cf1-00bc-42d2-bb5a-07f51df49f94>
Tue, 3 Sep 2002 03:28:00 +0000 (03:28 +0000)
49 files changed:
MANIFEST
Makefile
schema/mysql_build.pl
site/cgi-bin/admin/add.pl
site/cgi-bin/admin/admin.pl
site/cgi-bin/admin/generate.pl
site/cgi-bin/admin/move.pl
site/cgi-bin/admin/reorder.pl
site/cgi-bin/admin/shopadmin.pl
site/cgi-bin/admin/subs.pl
site/cgi-bin/bse.cfg
site/cgi-bin/modules/BSE/DB/Mysql.pm
site/cgi-bin/modules/BSE/Edit/Article.pm
site/cgi-bin/modules/BSE/Permissions.pm
site/cgi-bin/modules/BSE/Request.pm
site/cgi-bin/modules/BSE/UserReg.pm
site/cgi-bin/modules/BSE/Util/Tags.pm
site/cgi-bin/modules/DevHelp/Tags.pm
site/cgi-bin/modules/Generate.pm
site/cgi-bin/modules/Generate/Article.pm
site/cgi-bin/modules/Generate/Catalog.pm
site/cgi-bin/modules/Squirrel/Template.pm
site/docs/access.pod
site/docs/bse.pod
site/htdocs/admin/help/adduser.html
site/htdocs/admin/help/catalog.html
site/htdocs/admin/help/edit.html
site/htdocs/admin/help/file.html
site/htdocs/admin/help/image.html
site/htdocs/admin/help/product.html
site/htdocs/images/admin/checked.gif [new file with mode: 0755]
site/htdocs/images/admin/unchecked.gif [new file with mode: 0644]
site/templates/admin/article_img.tmpl
site/templates/admin/catalog.tmpl
site/templates/admin/edit_0.tmpl
site/templates/admin/edit_1.tmpl
site/templates/admin/edit_2.tmpl
site/templates/admin/edit_catalog.tmpl
site/templates/admin/edit_product.tmpl
site/templates/admin/filelist.tmpl
site/templates/admin/menu.tmpl
site/templates/admin/product_list.tmpl
site/templates/admin/subs/list.tmpl
site/templates/base.tmpl
site/templates/cart_base.tmpl
site/templates/checkout_base.tmpl
site/templates/checkoutfinal_base.tmpl
site/templates/user/options_base.tmpl
site/templates/user/userpage_base.tmpl

index 8881619..5a42c0d 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -157,10 +157,12 @@ site/htdocs/admin/index.html
 site/htdocs/css/admin.css
 site/htdocs/css/admin.css_natural
 site/htdocs/css/style-main.css
+site/htdocs/images/admin/checked.gif
 site/htdocs/images/admin/error.gif
 site/htdocs/images/admin/help.gif
 site/htdocs/images/admin/move_down.gif
 site/htdocs/images/admin/move_up.gif
+site/htdocs/images/admin/unchecked.gif
 site/htdocs/images/filestatus/download.gif
 site/htdocs/images/filestatus/forSale.gif
 site/htdocs/images/filestatus/locked.gif
index c0bd27a..90f83f1 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.12_11
+VERSION=0.12_12
 DISTNAME=bse-$(VERSION)
 DISTBUILD=$(DISTNAME)
 DISTTAR=../$(DISTNAME).tar
index 33c5e5e..c936192 100644 (file)
@@ -7,8 +7,6 @@ my $un = 'bsebuilder';
 my $pw = 'bsebuilder';
 my $dist = "/home/tony/dev/bse/base/bse/schema/bse.sql";
 
-system "/usr/local/mysql/bin/mysql -u$un -p$pw $db <$dist"
-  and die "Error loading database";
 my $dbh = DBI->connect("dbi:mysql:$db", $un, $pw)
   or die "Cannot connect to db: ",DBI->errstr;
 
@@ -16,6 +14,24 @@ my $tl = $dbh->prepare("show tables")
   or die "prepare show tables ",$dbh->errstr;
 $tl->execute
   or die "execute show tables ",$tl->errstr;
+# cleanup first
+my @drop_tables;
+while (my $row = $tl->fetchrow_arrayref) {
+  push(@drop_tables, $row->[0]);
+}
+undef $tl;
+for my $drop (@drop_tables) {
+  $dbh->do("drop table $drop")
+    or die "Could not drop old table: ", $dbh->errstr;
+}
+
+system "/usr/local/mysql/bin/mysql -u$un -p$pw $db <$dist"
+  and die "Error loading database";
+
+$tl = $dbh->prepare("show tables")
+  or die "prepare show tables ",$dbh->errstr;
+$tl->execute
+  or die "execute show tables ",$tl->errstr;
 my @tables;
 while (my $row = $tl->fetchrow_arrayref) {
   push(@tables, $row->[0]);
index ce4ff86..50c7e78 100755 (executable)
@@ -11,7 +11,15 @@ use BSE::Request;
 use BSE::Template;
 use Carp 'confess';
 
-$SIG{__DIE__} = sub { confess $@ };
+#  $SIG{__DIE__} = 
+#    sub { 
+#      if ($@ =~ /^ENOIMPL\b/) {
+#        die $@;
+#      }
+#      else {
+#        confess $@;
+#      }
+#    };
 
 my $req = BSE::Request->new;
 my $cgi = $req->cgi;
index 483eb66..75ca12d 100755 (executable)
@@ -4,28 +4,36 @@
 use strict;
 use FindBin;
 use CGI::Carp 'fatalsToBrowser';
-use CGI qw(:standard);
 #use Carp 'verbose'; # remove the 'verbose' in production
 use lib "$FindBin::Bin/../modules";
 use Articles;
-use BSE::Cfg;
+use BSE::Request;
+use Util 'refresh_to';
 
-my $id = param('id');
-defined $id or $id = 1;
-my $admin = 1;
-$admin = param('admin') if defined param('admin');
-
-my $cfg = BSE::Cfg->new;
-#my $articles = Articles->new;
-my $articles = 'Articles';
-
-my $article = $articles->getByPkey($id)
-  or die "Cannot find article ",$id;
-
-eval "use $article->{generator}";
-die $@ if $@;
-my $generator = $article->{generator}->new(admin=>$admin, articles=>$articles, cfg=>$cfg);
-
-print "Content-Type: text/html\n\n";
-print $generator->generate($article, $articles);
+my $req = BSE::Request->new;
+my $cfg = $req->cfg;
 
+if ($req->check_admin_logon()) {
+  my $cgi = $req->cgi;
+  my $id = $cgi->param('id');
+  defined $id or $id = 1;
+  my $admin = 1;
+  $admin = $cgi->param('admin') if defined $cgi->param('admin');
+  
+  #my $articles = Articles->new;
+  my $articles = 'Articles';
+  
+  my $article = $articles->getByPkey($id)
+    or die "Cannot find article ",$id;
+  
+  eval "use $article->{generator}";
+  die $@ if $@;
+  my $generator = $article->{generator}->new(admin=>$admin, articles=>$articles, cfg=>$cfg, request=>$req);
+  
+  print "Content-Type: text/html\n\n";
+  print $generator->generate($article, $articles);
+}
+else {
+  my $urlbase = $cfg->entryErr('site', 'url');
+  refresh_to("$urlbase/cgi-bin/admin/logon.pl");
+}
index 5547504..faa5c07 100755 (executable)
@@ -7,25 +7,33 @@ use CGI qw(:standard);
 use Constants;
 use Util qw(generate_button regen_and_refresh refresh_to);
 use Carp 'verbose';
-use BSE::Cfg;
+use BSE::Request;
 
-#my $articles = Articles->new;
-my $id = param('id');
-my $fromid = param('fromid') || $id;
+my $req = BSE::Request->new;
+
+my $cfg = $req->cfg;
+my $cgi = $req->cgi;
+my $siteurl = $cfg->entryErr('site', 'url');
+unless ($req->check_admin_logon()) {
+  refresh_to("$siteurl/cgi-bin/admin/logon.pl");
+  exit;
+}
+
+my $id = $cgi->param('id');
+my $fromid = $cgi->param('fromid') || $id;
 my $baseurl;
 if (defined $fromid
     and my $fromart = Articles->getByPkey($fromid)) {
   $baseurl = $fromart->{admin};
 }
 else {
-  $baseurl = "/admin/";
+  $baseurl = "/cgi-bin/admin/menu.pl";
 }
 
-my $cfg = BSE::Cfg->new;
-my $siteurl = $cfg->entryErr('site', 'url');
 if (generate_button()) {
   my $callback;
-  if (param('progress')) {
+  my $progress = $cgi->param('progress');
+  if ($progress) {
     $| = 1;
     print "Content-Type: text/html\n\n";
     print "<html><title>Regenerating your site</title></head><body>";
@@ -35,22 +43,37 @@ if (generate_button()) {
   if (defined $id) {
     use Util 'generate_article';
     my $article;
+    my $can;
     if ($id eq 'extras') {
       $article = 'extras';
+      $can = $req->user_can('regen_extras');
     }
     else {
       $article = Articles->getByPkey($id)
        or die "No such article $id found";
+      $can = $req->user_can('regen_article', $article);
+    }
+    if ($can) {
+      regen_and_refresh('Articles', $article, 1, 
+                       $siteurl . $baseurl, $cfg, $callback);
+    }
+    else {
+      print "<p>You don't have permission to regenerate that</p>\n"
+       if $progress;
     }
-    regen_and_refresh('Articles', $article, 1, 
-                     $siteurl . $baseurl, $cfg, $callback);
   }
   else {
-    regen_and_refresh('Articles', undef, 1, 
-                     $siteurl . $baseurl, $cfg, $callback);
+    if ($req->user_can('regen_all')) {
+      regen_and_refresh('Articles', undef, 1, 
+                       $siteurl . $baseurl, $cfg, $callback);
+    }
+    else {
+      print "<p>You don't have permission to regen all.</p>\n"
+       if $progress;
+    }
   }
-  if (param('progress')) {
-    print qq!<p>Done <a href="/admin/">Return to admin menu</a></p>\n!;
+  if ($progress) {
+    print qq!<p>Done <a href="/cgi-bin/admin/menu.pl">Return to admin menu</a></p>\n!;
     print "</body></html>\n";
   }
 }
index 885ad54..f52623f 100755 (executable)
@@ -9,124 +9,139 @@ use Articles;
 use CGI ':standard';
 use Carp 'verbose';
 use CGI::Carp 'fatalsToBrowser';
+use BSE::Request;
 use Constants;
 
-my $cfg = BSE::Cfg->new;
+my $req = BSE::Request->new;
+unless ($req->check_admin_logon()) {
+  print "Refresh: 0; url=\"$urlbase/cgi-bin/admin/logon.pl\"\n";
+  exit;
+}
+
+my $cfg = $req->cfg;
+my $cgi = $req->cgi;
 my $urlbase = $cfg->entryVar('site', 'url');
 
-my $id = param('id');
-my $direction = param('d');
+my $id = $cgi->param('id');
+my $direction = $cgi->param('d');
 
 my $articles = Articles->new;
   
 my $article;
-if (defined param('stepchild')) {
-  # we always need a swap for this one
-  my $stepchild = param('stepchild');
-
-  my $article = Articles->getByPkey($stepchild)
-    or die "Cannot find child $stepchild";
-
-  my $other = param('other');
-
-  require 'OtherParents.pm';
-  my $one = OtherParents->getBy(parentId=>$id, childId=>$stepchild)
-    or die "Cannot find link between child $stepchild and parent $id";
-  my $two = OtherParents->getBy(parentId=>$other, childId=>$stepchild)
-    or die "Cannot find link between child $stepchild and parent $other";
-  ($one->{childDisplayOrder}, $two->{childDisplayOrder}) =
-    ($two->{childDisplayOrder}, $one->{childDisplayOrder});
-  $one->save;
-  $two->save;
-  use Util 'generate_article';
-  generate_article('Articles', $article);
+if (defined $cgi->param('stepchild')) {
+  my $stepchild = $cgi->param('stepchild');
+  if ($req->user_can(edit_reorder_stepparents=>$stepchild)) {
+    # we always need a swap for this one
+    
+    my $article = Articles->getByPkey($stepchild)
+      or die "Cannot find child $stepchild";
+    
+    my $other = $cgi->param('other');
+    
+    require 'OtherParents.pm';
+    my $one = OtherParents->getBy(parentId=>$id, childId=>$stepchild)
+      or die "Cannot find link between child $stepchild and parent $id";
+    my $two = OtherParents->getBy(parentId=>$other, childId=>$stepchild)
+      or die "Cannot find link between child $stepchild and parent $other";
+    ($one->{childDisplayOrder}, $two->{childDisplayOrder}) =
+      ($two->{childDisplayOrder}, $one->{childDisplayOrder});
+    $one->save;
+    $two->save;
+    use Util 'generate_article';
+    generate_article('Articles', $article);
+  }
 }
-elsif (defined param('stepparent')) {
+elsif (defined $cgi->param('stepparent')) {
   require 'OtherParents.pm';
 
-  my $stepparent = param('stepparent');
-  my $other = param('other');
-  my $onename = 'parentDisplayOrder';
-  my $one = OtherParents->getBy(parentId=>$stepparent, childId=>$id);
-  unless ($one) {
-    $onename = 'displayOrder';
-    $one = Articles->getByPkey($id)
-      or die "Could not find article $id";
+  my $stepparent = $cgi->param('stepparent');
+  if ($req->user_can(edit_reorder_children => $stepparent)) {
+    my $other = $cgi->param('other');
+    my $onename = 'parentDisplayOrder';
+    my $one = OtherParents->getBy(parentId=>$stepparent, childId=>$id);
+    unless ($one) {
+      $onename = 'displayOrder';
+      $one = Articles->getByPkey($id)
+       or die "Could not find article $id";
+    }
+    my $twoname = 'parentDisplayOrder';
+    my $two = OtherParents->getBy(parentId=>$stepparent, childId=>$other);
+    unless ($two) {
+      $twoname = 'displayOrder';
+      $two = Articles->getByPkey($other)
+       or die "Could not find article $other";
+    }
+    ($one->{$onename}, $two->{$twoname}) = ($two->{$twoname}, $one->{$onename});
+    $one->save;
+    $two->save;
+    use Util 'generate_article';
+    generate_article('Articles', $article);
   }
-  my $twoname = 'parentDisplayOrder';
-  my $two = OtherParents->getBy(parentId=>$stepparent, childId=>$other);
-  unless ($two) {
-    $twoname = 'displayOrder';
-    $two = Articles->getByPkey($other)
-      or die "Could not find article $other";
-  }
-  ($one->{$onename}, $two->{$twoname}) = ($two->{$twoname}, $one->{$onename});
-  $one->save;
-  $two->save;
-  use Util 'generate_article';
-  generate_article('Articles', $article);
 }
 else {
   $article = $articles->getByPkey($id)
     or die "Could not find article $id";
-  
-  # get our siblings, in order
-  my @siblings;
-  if (param('all')) {
-    @siblings = sort { $b->{displayOrder} <=> $a->{displayOrder} }
-      $articles->children($article->{parentid});
-  }
-  else {
-    @siblings = $articles->listedChildren($article->{parentid});
-  }
-  
-  # find our article
-  my $index;
-  for ($index = 0; $index < @siblings; ++$index) {
-    last if $siblings[$index]{id} == $id;
-  }
-  
-  die "This program is broken - couldn't find self in list of parents children"
-    if $index == @siblings;
-  
-  if ($direction eq 'down') {
-    die "There is no next article to swap with"
-      if $index == $#siblings;
-    ($article->{displayOrder}, $siblings[$index+1]{displayOrder})
-      = ($siblings[$index+1]{displayOrder}, $article->{displayOrder});
-    $siblings[$index+1]->save();
-  }
-  elsif ($direction eq 'up') {
-    die "There is no previous article to swap with"
-      if $index == 0;
-    ($article->{displayOrder}, $siblings[$index-1]{displayOrder})
-      = ($siblings[$index-1]{displayOrder}, $article->{displayOrder});
-    $siblings[$index-1]->save();
+
+  if ($req->user_can(edit_reorder_children => $article->{parentid})) {
+    # get our siblings, in order
+    my @siblings;
+    if ($cgi->param('all')) {
+      @siblings = sort { $b->{displayOrder} <=> $a->{displayOrder} }
+       $articles->children($article->{parentid});
+    }
+    else {
+      @siblings = $articles->listedChildren($article->{parentid});
+    }
     
-  }
-  elsif ($direction eq 'swap') {
-    my $other = param('other')
-      or die "Need to specify an 'other' article to swap with";
-    my ($other_index) = grep $siblings[$_]{id} == $other, 0..$#siblings;
-    defined $other_index or die "No such such sibling";
+    # find our article
+    my $index;
+    for ($index = 0; $index < @siblings; ++$index) {
+      last if $siblings[$index]{id} == $id;
+    }
     
-    ($article->{displayOrder}, $siblings[$other_index]{displayOrder})
-      = ($siblings[$other_index]{displayOrder}, $article->{displayOrder});
-    $siblings[$other_index]->save();
-  }
-  else {
-    die "Sorry, can't move articles sideways";
+    die "This program is broken - couldn't find self in list of parents children"
+      if $index == @siblings;
+    
+    if ($direction eq 'down') {
+      die "There is no next article to swap with"
+       if $index == $#siblings;
+      ($article->{displayOrder}, $siblings[$index+1]{displayOrder})
+       = ($siblings[$index+1]{displayOrder}, $article->{displayOrder});
+      $siblings[$index+1]->save();
+    }
+    
+    elsif ($direction eq 'up') {
+      die "There is no previous article to swap with"
+       if $index == 0;
+      ($article->{displayOrder}, $siblings[$index-1]{displayOrder})
+       = ($siblings[$index-1]{displayOrder}, $article->{displayOrder});
+      $siblings[$index-1]->save();
+      
+    }
+    elsif ($direction eq 'swap') {
+      my $other = $cgi->param('other')
+       or die "Need to specify an 'other' article to swap with";
+      my ($other_index) = grep $siblings[$_]{id} == $other, 0..$#siblings;
+      defined $other_index or die "No such such sibling";
+      
+      ($article->{displayOrder}, $siblings[$other_index]{displayOrder})
+       = ($siblings[$other_index]{displayOrder}, $article->{displayOrder});
+      $siblings[$other_index]->save();
+    }
+    else {
+      die "Sorry, can't move articles sideways";
+    }
+    
+    $article->save();
+    use Util 'generate_article';
+    generate_article('Articles', $article);
   }
-
-  $article->save();
-  use Util 'generate_article';
-  generate_article('Articles', $article);
 }
 
-if (param('refreshto')) {
-  print "Refresh: 0; url=\"$urlbase",param('refreshto'),"\"\n";
+if ($cgi->param('refreshto')) {
+  print "Refresh: 0; url=\"$urlbase",$cgi->param('refreshto'),"\"\n";
 }
-elsif (param('edit')) {
+elsif ($cgi->param('edit')) {
   # refresh back to editor
   print "Refresh: 0; url=\"$urlbase/cgi-bin/admin/add.pl?id=$article->{parentid}#children\"\n";
 }
index dd87aa6..2cb3fc6 100755 (executable)
@@ -5,83 +5,91 @@ use strict;
 use FindBin;
 use lib "$FindBin::Bin/../modules";
 use Articles;
-use CGI qw(:standard);
-use BSE::Cfg;
+use BSE::Request;
 use vars qw($VERSION);
 $VERSION = 1.02;
 
-my $cfg = BSE::Cfg->new;
+my $req = BSE::Request->new;
+my $cfg = $req->cfg;
+my $cgi = $req->cgi;
 my $urlbase = $cfg->entryVar('site', 'url');
+unless ($req->check_admin_logon()) {
+  print "Refresh: 0; url=\"$urlbase/cgi-bin/admin/logon.pl\"\n";
+  print "Content-Type: text/html\n\n<html></html>\n";
+  exit;
+}
 
-my $refreshto = param('refreshto') || '/admin/';
+my $refreshto = $cgi->param('refreshto') || '/cgi-bin/admin/menu.pl';
 # each entry of @kids is an arrayref containing the article
 # to get sort data from, the actual object, and the field in the actual
 # object containing the display order value
 my @kids;
 my %kids;
-my $parentid = param('parentid');
-my $stepparent = param('stepparent');
-my $stepchild = param('stepchild');
-if ($parentid) {
-  $parentid += 0;
-  @kids = map [$_, $_, 'displayOrder' ], Articles->getBy(parentid=>$parentid);
-}
-elsif ($stepparent) {
-  require 'OtherParents.pm';
-
-  my $parent = Articles->getByPkey($stepparent);
-  if ($parent) {
-    my @otherlinks = OtherParents->getBy(parentId=>$stepparent);
-    my @normalkids = Articles->listedChildren($stepparent);
-    my @stepkids = $parent->stepkids;
-    my %stepkids = map { $_->{id}, $_ } @stepkids;
-    @kids = (
-            map([ $_, $_, 'displayOrder' ], @normalkids),
-            map([ $stepkids{$_->{childId}}, $_, 'parentDisplayOrder' ],
-                @otherlinks),
-           );
+my $parentid = $cgi->param('parentid');
+if ($req->user_can(edit_reorder_children => $parentid)) {
+  my $stepparent = $cgi->param('stepparent');
+  my $stepchild = $cgi->param('stepchild');
+  if ($parentid) {
+    $parentid += 0;
+    @kids = map [$_, $_, 'displayOrder' ], Articles->getBy(parentid=>$parentid);
   }
-}
-elsif ($stepchild) {
-  require 'OtherParents.pm';
-
-  my $child = Articles->getByPkey($stepchild);
-  if ($child) {
-    my @otherlinks = OtherParents->getBy(childId=>$stepchild);
-    my @stepparents = map Articles->getByPkey($_->{parentId}), @otherlinks;
-    my %stepparents = map { $_->{id}, $_ } @stepparents;
-    @kids = (
-            map([ $stepparents{$_->{parentId}}, $_, 'childDisplayOrder' ],
-                @otherlinks),
-           );
+  elsif ($stepparent) {
+    require 'OtherParents.pm';
+    
+    my $parent = Articles->getByPkey($stepparent);
+    if ($parent) {
+      my @otherlinks = OtherParents->getBy(parentId=>$stepparent);
+      my @normalkids = Articles->listedChildren($stepparent);
+      my @stepkids = $parent->stepkids;
+      my %stepkids = map { $_->{id}, $_ } @stepkids;
+      @kids = (
+              map([ $_, $_, 'displayOrder' ], @normalkids),
+              map([ $stepkids{$_->{childId}}, $_, 'parentDisplayOrder' ],
+                  @otherlinks),
+             );
+    }
   }
-}
-
-
-my @order = sort { $b <=> $a } map $_->[1]{$_->[2]}, @kids;
-my $sort = param('sort') || 'current';
-my $reverse = param('reverse');
-
-my $code;
-if ($sort eq 'title') {
-  $code = sub { lc($a->[0]{title}) cmp lc($b->[0]{title}) };
-}
-elsif ($sort eq 'date') {
-  $code = sub { $a->[0]{lastModified} cmp $b->[0]{lastModified} };
-}
-elsif ($sort eq 'current') {
-  $code = sub { $b->[1]{$b->[2]} <=> $a->[1]{$a->[2]} };
-}
-if ($reverse) {
-  my $temp = $code;
-  $code = sub { -$temp->() };
-}
-if ($code) {
-  @kids = sort $code @kids;
-  for my $i (0..$#kids) {
-    my $kid = $kids[$i];
-    $kid->[1]{$kid->[2]} = $order[$i];
-    $kid->[1]->save();
+  elsif ($stepchild) {
+    require 'OtherParents.pm';
+    
+    my $child = Articles->getByPkey($stepchild);
+    if ($child) {
+      my @otherlinks = OtherParents->getBy(childId=>$stepchild);
+      my @stepparents = map Articles->getByPkey($_->{parentId}), @otherlinks;
+      my %stepparents = map { $_->{id}, $_ } @stepparents;
+      @kids = (
+              map([ $stepparents{$_->{parentId}}, $_, 'childDisplayOrder' ],
+                  @otherlinks),
+             );
+    }
+  }
+  
+  
+  my @order = sort { $b <=> $a } map $_->[1]{$_->[2]}, @kids;
+  my $sort = $cgi->param('sort') || 'current';
+  my $reverse = $cgi->param('reverse');
+  
+  my $code;
+  if ($sort eq 'title') {
+    $code = sub { lc($a->[0]{title}) cmp lc($b->[0]{title}) };
+  }
+  elsif ($sort eq 'date') {
+    $code = sub { $a->[0]{lastModified} cmp $b->[0]{lastModified} };
+  }
+  elsif ($sort eq 'current') {
+    $code = sub { $b->[1]{$b->[2]} <=> $a->[1]{$a->[2]} };
+  }
+  if ($reverse) {
+    my $temp = $code;
+    $code = sub { -$temp->() };
+  }
+  if ($code) {
+    @kids = sort $code @kids;
+    for my $i (0..$#kids) {
+      my $kid = $kids[$i];
+      $kid->[1]{$kid->[2]} = $order[$i];
+      $kid->[1]->save();
+    }
   }
 }
 
index d9e2e57..5637d05 100755 (executable)
@@ -5,7 +5,6 @@ BEGIN { $ENV{DISPLAY} = '192.168.32.97:0.0'; }
 use strict;
 use FindBin;
 use lib "$FindBin::Bin/../modules";
-use CGI ':standard';
 
 #use Carp; # 'verbose';
 use Products;
@@ -22,16 +21,21 @@ use Constants qw(:shop $SHOPID $PRODUCTPARENT
 use Images;
 use Articles;
 use BSE::Sort;
-use BSE::Cfg;
-use BSE::Session;
 use BSE::Util::Tags;
+use BSE::Request;
 
-my $cfg = BSE::Cfg->new();
+my $req = BSE::Request->new;
+my $cfg = $req->cfg;
 my $securlbase = $cfg->entryVar('site', 'secureurl');
-my %session;
-BSE::Session->tie_it(\%session, $cfg);
+my $baseurl =  $cfg->entryVar('site', 'url');
+unless ($req->check_admin_logon()) {
+  refresh_to("$baseurl/cgi-bin/admin/logon.pl");
+  exit;
+}
+#my %session;
+#BSE::Session->tie_it(\%session, $cfg);
 
-param();
+#param();
 
 my %what_to_do =
   (
@@ -44,8 +48,8 @@ my %what_to_do =
 #     edit_product=>\&edit_product,
 #     add_product=>\&add_product,
 #     save_product=>\&save_product,
-   delete_product=>\&delete_product,
-   undelete_product=>\&undelete_product,
+#   delete_product=>\&delete_product,
+#   undelete_product=>\&undelete_product,
    product_detail=>\&product_detail,
 #     add_stepcat=>\&add_stepcat,
 #     del_stepcat=>\&del_stepcat,
@@ -58,31 +62,31 @@ my @modifiable = qw(body retailPrice wholesalePrice gst release expire
                     summaryLength);
 my %modifiable = map { $_=>1 } @modifiable;
 
-my $product;
-my $id = param('id');
-if ($id) {
-  $product = Products->getByPkey($id);
-}
-else {
-  my $parentid = param('parentid');
-  if ($parentid) {
-    $product = { parentid=>$parentid };
-  }
-}
-my %acts;
-%acts = 
-  (
-   BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
-   BSE::Util::Tags->admin(\%acts, $cfg),
-   articleType=>sub { 'Product' },
-   article=>
-   sub {
-     my $value = $product->{$_[0]};
-     defined $value or $value = '';
-     CGI::escapeHTML($value);
-   },
-   level => sub { 3; }, # doesn't really matter here
-  );
+#  my $product;
+#  my $id = param('id');
+#  if ($id) {
+#    $product = Products->getByPkey($id);
+#  }
+#  else {
+#    my $parentid = param('parentid');
+#    if ($parentid) {
+#      $product = { parentid=>$parentid };
+#    }
+#  }
+#  my %acts;
+#  %acts = 
+#    (
+#     BSE::Util::Tags->basic(\%acts, $req->cgi, $cfg),
+#     BSE::Util::Tags->admin(\%acts, $cfg),
+#     articleType=>sub { 'Product' },
+#     article=>
+#     sub {
+#       my $value = $product->{$_[0]};
+#       defined $value or $value = '';
+#       CGI::escapeHTML($value);
+#     },
+#     level => sub { 3; }, # doesn't really matter here
+#    );
 
 #  my $imageEditor = Squirrel::ImageEditor->new(session=>\%session,
 #                                           extras=>\%acts,
@@ -101,25 +105,29 @@ my %acts;
 #    exit;
 #  }
 
-while (my ($key, $func) = each %what_to_do) {
-  if (param($key)) {
-    $func->();
-    exit;
+{
+  my $cgi = $req->cgi;
+  while (my ($key, $func) = each %what_to_do) {
+    if ($cgi->param($key)) {
+      $func->($req);
+      exit;
+    }
   }
 }
 
-product_list();
+product_list($req);
 
 #####################
 # product management
 
 sub embedded_catalog {
-  my ($catalog, $template) = @_;
+  my ($req, $catalog, $template) = @_;
 
+  my $session = $req->session;
   use POSIX 'strftime';
   my $products = Products->new;
   my @list;
-  if ($session{showstepkids}) {
+  if ($session->{showstepkids}) {
     @list = grep $_->{generator} eq 'Generate::Product', $catalog->allkids;
     @list = map { $products->getByPkey($_->{id}) } @list;
   }
@@ -138,6 +146,7 @@ sub embedded_catalog {
     (
      BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
      BSE::Util::Tags->admin(\%acts, $cfg),
+     BSE::Util::Tags->secure($req),
      catalog => sub { CGI::escapeHTML($catalog->{$_[0]}) },
      date => sub { display_date($list[$list_index]{$_[0]}) },
      money => sub { sprintf("%.2f", $list[$list_index]{$_[0]}/100.0) },
@@ -159,11 +168,13 @@ sub embedded_catalog {
      sub { $list[$list_index]{listed} == 0 ? "Hidden" : "&nbsp;" },
      move =>
      sub {
+       $req->user_can(edit_reorder_children => $catalog)
+        or return '';
        # links to move products up/down
        my $html = '';
        my $refreshto = CGI::escape($ENV{SCRIPT_NAME}."#cat".$catalog->{id});
        if ($list_index < $#list) {
-        if ($session{showstepkids}) {
+        if ($session->{showstepkids}) {
           $html .= <<HTML;
 <a href="$CGI_URI/admin/move.pl?stepparent=$catalog->{id}&d=swap&id=$list[$list_index]{id}&other=$list[$list_index+1]{id}&refreshto=$refreshto"><img src="$IMAGES_URI/admin/move_down.gif" width="17" height="13" border="0" alt="Move Down" align="absbottom"></a>
 HTML
@@ -175,7 +186,7 @@ HTML
         }
        }
        if ($list_index > 0) {
-        if ($session{showstepkids}) {
+        if ($session->{showstepkids}) {
           $html .= <<HTML;
 <a href="$CGI_URI/admin/move.pl?stepparent=$catalog->{id}&d=swap&id=$list[$list_index]{id}&other=$list[$list_index-1]{id}&refreshto=$refreshto"><img src="$IMAGES_URI/admin/move_up.gif" width="17" height="13" border="0" alt="Move Up" align="absbottom"></a>
 HTML
@@ -193,10 +204,12 @@ HTML
      sub {
        my ($which, $template) = split ' ', $_[0];
        $which eq 'subcat' or return "Unknown object $which embedded";
-       return embedded_catalog($subcats[$subcat_index], $template);
+       return embedded_catalog($req, $subcats[$subcat_index], $template);
      },
      movecat =>
      sub {
+       $req->user_can(edit_reorder_children => $catalog)
+        or return '';
        # links to move catalogs up/down
        my $html = '';
        my $refreshto = CGI::escape($ENV{SCRIPT_NAME});
@@ -219,31 +232,40 @@ HTML
 }
 
 sub product_list {
+  my ($req, $message) = @_;
+
+  my $cgi = $req->cgi;
+  my $session = $req->session;
+  my $shopid = $req->cfg->entryErr('articles', 'shop');
   my @catalogs = sort { $b->{displayOrder} <=> $a->{displayOrder} }
-    Articles->children($SHOPID);
+    Articles->children($shopid);
   my $catalog_index = -1;
-  my $message = param('message') || shift || '';
-  if (defined param('showstepkids')) {
-    $session{showstepkids} = param('showstepkids');
+  $message ||= $cgi->param('message') || '';
+  if (defined $cgi->param('showstepkids')) {
+    $session->{showstepkids} = $cgi->param('showstepkids');
   }
-  exists $session{showstepkids} or $session{showstepkids} = 1;
-  my %acts =
+  exists $session->{showstepkids} or $session->{showstepkids} = 1;
+  my %acts;
+  %acts =
     (
-     BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
+     BSE::Util::Tags->basic(\%acts, $cgi, $cfg),
      BSE::Util::Tags->admin(\%acts, $cfg),
+     BSE::Util::Tags->secure($req),
      catalog=> sub { CGI::escapeHTML($catalogs[$catalog_index]{$_[0]}) },
      iterate_catalogs => sub { ++$catalog_index < @catalogs  },
-     shopid=>sub { $SHOPID },
+     shopid=>sub { $shopid },
      script=>sub { $ENV{SCRIPT_NAME} },
      message => sub { $message },
      embed =>
      sub {
        my ($which, $template) = split ' ', $_[0];
        $which eq 'catalog' or return "Unknown object $which embedded";
-       return embedded_catalog($catalogs[$catalog_index], $template);
+       return embedded_catalog($req, $catalogs[$catalog_index], $template);
      },
      movecat =>
      sub {
+       $req->user_can(edit_reorder_children => $shopid)
+        or return '';
        # links to move catalogs up/down
        my $html = '';
        my $refreshto = CGI::escape($ENV{SCRIPT_NAME});
@@ -259,245 +281,251 @@ HTML
        }
        return $html;
      },
-     ifShowStepKids => sub { $session{showstepkids} },
+     ifShowStepKids => sub { $session->{showstepkids} },
     );
 
   page('product_list', \%acts);
 }
 
-sub add_product {
-  my $product = { map { $_=>'' } Product->columns };
-
-  $product->{leadTime} = 0;
-  @$product{qw/retailPrice wholesalePrice gst/} = qw(0 0 0);
-  use BSE::Util::SQL qw(now_sqldate);
-  $product->{release} = now_sqldate;
-  $product->{expire} = '9999-12-31';
-  $product->{parentid} = param('parentid')
-    if param('parentid');
-  if ($product->{parentid}) {
-    my $parent = Articles->getByPkey($product->{parentid});
-    if ($parent) {
-      $product->{threshold} = $parent->{threshold};
-      $product->{summaryLength} = $parent->{summaryLength};
-    }
-  }
-#    if (!exists $session{imageid} || $session{imageid} ne '') {
-#      $session{imageid} = '';
-#      #$imageEditor->set([], 'tr');
+#  sub add_product {
+
+#    my $product = { map { $_=>'' } Product->columns };
+
+#    $product->{leadTime} = 0;
+#    @$product{qw/retailPrice wholesalePrice gst/} = qw(0 0 0);
+#    use BSE::Util::SQL qw(now_sqldate);
+#    $product->{release} = now_sqldate;
+#    $product->{expire} = '9999-12-31';
+#    $product->{parentid} = param('parentid')
+#      if param('parentid');
+#    if ($product->{parentid}) {
+#      my $parent = Articles->getByPkey($product->{parentid});
+#      if ($parent) {
+#        $product->{threshold} = $parent->{threshold};
+#        $product->{summaryLength} = $parent->{summaryLength};
+#      }
 #    }
+#  #    if (!exists $session{imageid} || $session{imageid} ne '') {
+#  #      $session{imageid} = '';
+#  #      #$imageEditor->set([], 'tr');
+#  #    }
 
-  product_form($product, "Add New");
-}
+#    product_form($product, "Add New");
+#  }
 
-sub edit_product {
-  my $id = param('id');
-  $id or shop_redirect('?product_list=1');
-  my $product = Products->getByPkey($id)
-    or shop_redirect("?message=Product+$id+not+found");
-#    if (!exists $session{imageid} || $session{imageid} != $id) {
-#      my @images = Images->getBy('articleId', $id);
-#      $session{imageid} = $id;
-#      $imageEditor->set(\@images, $product->{imagePos});
-#    }
+#  sub edit_product {
+#    my $id = param('id');
+#    $id or shop_redirect('?product_list=1');
+#    my $product = Products->getByPkey($id)
+#      or shop_redirect("?message=Product+$id+not+found");
+#  #    if (!exists $session{imageid} || $session{imageid} != $id) {
+#  #      my @images = Images->getBy('articleId', $id);
+#  #      $session{imageid} = $id;
+#  #      $imageEditor->set(\@images, $product->{imagePos});
+#  #    }
   
-  product_form($product, "Edit", '', 'edit_product');
-}
+#    product_form($product, "Edit", '', 'edit_product');
+#  }
 
-sub save_product {
-  my %product;
+#  sub save_product {
+#    my %product;
 
-  for my $col (Product->columns) {
-    $product{$col} = param($col) if defined param($col);
-  }
+#    for my $col (Product->columns) {
+#      $product{$col} = param($col) if defined param($col);
+#    }
 
-  my $original;
-  # we validate in here
-  eval {
-    if ($product{id}) {
-      $original = Products->getByPkey($product{id})
-       or shop_redirect("?message=Product+$product{id}+not+found");
-    }
-    money_to_cents(\$product{retailPrice})
-      or die "Invalid price\n";
-    money_to_cents(\$product{wholesalePrice})
-      or $product{wholesalePrice} = undef;
-    money_to_cents(\$product{gst})
-      or die "Invalid gst\n";
+#    my $original;
+#    # we validate in here
+#    eval {
+#      if ($product{id}) {
+#        $original = Products->getByPkey($product{id})
+#      or shop_redirect("?message=Product+$product{id}+not+found");
+#      }
+#      money_to_cents(\$product{retailPrice})
+#        or die "Invalid price\n";
+#      money_to_cents(\$product{wholesalePrice})
+#        or $product{wholesalePrice} = undef;
+#      money_to_cents(\$product{gst})
+#        or die "Invalid gst\n";
     
-    if ($original) {
-      # remove unmodifiable fields
-      for my $key (keys %product) {
-       $modifiable{$key} or delete $product{$key};
-      }
-    }
-    else {
-      $product{title} !~ /^\s*$/
-       or die "No title entered\n";
-      $product{summary} !~ /^\s*$/
-       or die "No summary entered\n";
-      $product{body} !~ /^\s*$/
-       or die "No description entered\n";
-      $product{leadTime} =~ /^\d+$/
-       or die "No lead time entered\n";
+#      if ($original) {
+#        # remove unmodifiable fields
+#        for my $key (keys %product) {
+#      $modifiable{$key} or delete $product{$key};
+#        }
+#      }
+#      else {
+#        $product{title} !~ /^\s*$/
+#      or die "No title entered\n";
+#        $product{summary} !~ /^\s*$/
+#      or die "No summary entered\n";
+#        $product{body} !~ /^\s*$/
+#      or die "No description entered\n";
+#        $product{leadTime} =~ /^\d+$/
+#      or die "No lead time entered\n";
 
-    }
-    use AdminUtil 'save_thumbnail';
-    save_thumbnail($original, \%product);
-    sql_date(\$product{release})
-      or die "Invalid release date\n";
-    sql_date(\$product{expire})
-      or die "Invalid expiry date\n";
-    # options should only contain valid options
-    my @bad_opts = grep !$SHOP_PRODUCT_OPTS{$_}, 
-    split /,/, $product{options};
-    @bad_opts
-      and die "Bad product options '",join(',',@bad_opts),"' entered\n";
-  };
-  if ($@) {
-    # CGI::Carp messes with the die message <sigh>
-    $@ =~ s/\[[^\]]*\][^:]+://; 
-    if ($original) {
-      for my $key (keys %$original) {
-       $product{$key} = $original->{$key};
-      }
-    }
-    product_form(\%product, $original ? "Edit" : "Add New", $@);
-    return;
-  }
+#      }
+#      use AdminUtil 'save_thumbnail';
+#      save_thumbnail($original, \%product);
+#      sql_date(\$product{release})
+#        or die "Invalid release date\n";
+#      sql_date(\$product{expire})
+#        or die "Invalid expiry date\n";
+#      # options should only contain valid options
+#      my @bad_opts = grep !$SHOP_PRODUCT_OPTS{$_}, 
+#      split /,/, $product{options};
+#      @bad_opts
+#        and die "Bad product options '",join(',',@bad_opts),"' entered\n";
+#    };
+#    if ($@) {
+#      # CGI::Carp messes with the die message <sigh>
+#      $@ =~ s/\[[^\]]*\][^:]+://; 
+#      if ($original) {
+#        for my $key (keys %$original) {
+#      $product{$key} = $original->{$key};
+#        }
+#      }
+#      product_form(\%product, $original ? "Edit" : "Add New", $@);
+#      return;
+#    }
 
-  # save the product
-  $product{parentid} ||= $PRODUCTPARENT;
+#    # save the product
+#    $product{parentid} ||= $PRODUCTPARENT;
 
-  my $parent = Articles->getByPkey($product{parentid})
-    or return product_form(\%product, $original ? "Edit" : "Add New",
-                          "Unknown parent id");
+#    my $parent = Articles->getByPkey($product{parentid})
+#      or return product_form(\%product, $original ? "Edit" : "Add New",
+#                         "Unknown parent id");
 
-  $product{titleImage} = '';
-  $product{keyword} ||= '';
-  $product{template} ||= 'shopitem.tmpl';
-  $product{level} = $parent->{level} + 1;
-  $product{lastModified} = epoch_to_sql(time);
-  $product{imagePos} = 'tr';
-  $product{generator} = 'Generate::Product';
+#    $product{titleImage} = '';
+#    $product{keyword} ||= '';
+#    $product{template} ||= 'shopitem.tmpl';
+#    $product{level} = $parent->{level} + 1;
+#    $product{lastModified} = epoch_to_sql(time);
+#    $product{imagePos} = 'tr';
+#    $product{generator} = 'Generate::Product';
   
-  if ($original) {
-    @$original{keys %product} = values %product;
-    $original->save();
-
-    # out with the old
-#      my @oldimages = Images->getBy('articleId', $original->{id});
-#      for my $image (@oldimages) {
-#        $image->remove();
-#      }
-#      # in with the new
-#      my @images = $imageEditor->images();
-#      my @cols = Image->columns;
-#      splice @cols, 0, 2;
-#      for my $image (@images) {
-#        Images->add($original->{id}, @$image{@cols});
-#      }
-#      $imageEditor->clear();
-#      delete $session{imageid};
-
-    use Util 'regen_and_refresh';
+#    if ($original) {
+#      @$original{keys %product} = values %product;
+#      $original->save();
+
+#      # out with the old
+#  #      my @oldimages = Images->getBy('articleId', $original->{id});
+#  #      for my $image (@oldimages) {
+#  #        $image->remove();
+#  #      }
+#  #      # in with the new
+#  #      my @images = $imageEditor->images();
+#  #      my @cols = Image->columns;
+#  #      splice @cols, 0, 2;
+#  #      for my $image (@images) {
+#  #        Images->add($original->{id}, @$image{@cols});
+#  #      }
+#  #      $imageEditor->clear();
+#  #      delete $session{imageid};
+
+#      use Util 'regen_and_refresh';
     
-    regen_and_refresh('Articles', $original, $AUTO_GENERATE,
-                     shop_url("?message=Saved")); 
+#      regen_and_refresh('Articles', $original, $AUTO_GENERATE,
+#                    shop_url("?message=Saved")); 
 
-    exit;
-  }
-  else {
-    # set these properly afterwards
-    $product{link} = '';
-    $product{admin} = '';
-    $product{listed} = 2;
-    $product{displayOrder} = time;
-
-    for my $col (qw(threshold summaryLength)) {
-      $product{$col} = $parent->{$col} unless exists $product{$col};
-    }
+#      exit;
+#    }
+#    else {
+#      # set these properly afterwards
+#      $product{link} = '';
+#      $product{admin} = '';
+#      $product{listed} = 2;
+#      $product{displayOrder} = time;
+
+#      for my $col (qw(threshold summaryLength)) {
+#        $product{$col} = $parent->{$col} unless exists $product{$col};
+#      }
 
-    my @data = @product{Product->columns};
-    shift @data;
+#      my @data = @product{Product->columns};
+#      shift @data;
 
-    my $product = Products->add(@data);
-    if (!$product) {
-      for my $key (keys %$original) {
-       $product{$key} = $original->{$key} unless defined $product{$key};
-      }
-      product_form(\%product, "Add New", DBI->errstr);
-    }
-    else {
-      # update the link info
-      $product->{link} = $securlbase . $SHOP_URI . '/shop'.$product->{id}.'.html';
-      $product->{admin} = "$CGI_URI/admin/admin.pl?id=$product->{id}";
-      $product->save();
-
-      # and save the images
-#        my @images = $imageEditor->images();
-#        for my $image (@images) {
-#      Images->add($product->{id}, @$image{qw/image alt width height/});
+#      my $product = Products->add(@data);
+#      if (!$product) {
+#        for my $key (keys %$original) {
+#      $product{$key} = $original->{$key} unless defined $product{$key};
 #        }
-#        $imageEditor->clear();
-#        delete $session{imageid};
-
-      use Util 'regen_and_refresh';
+#        product_form(\%product, "Add New", DBI->errstr);
+#      }
+#      else {
+#        # update the link info
+#        $product->{link} = $securlbase . $SHOP_URI . '/shop'.$product->{id}.'.html';
+#        $product->{admin} = "$CGI_URI/admin/admin.pl?id=$product->{id}";
+#        $product->save();
+
+#        # and save the images
+#  #        my @images = $imageEditor->images();
+#  #        for my $image (@images) {
+#  #   Images->add($product->{id}, @$image{qw/image alt width height/});
+#  #        }
+#  #        $imageEditor->clear();
+#  #        delete $session{imageid};
+
+#        use Util 'regen_and_refresh';
       
-      regen_and_refresh('Articles', $original, $AUTO_GENERATE,
-                       shop_url("?message=New+Product+Saved"));
-      exit;
-    }
-  }
-}
+#        regen_and_refresh('Articles', $original, $AUTO_GENERATE,
+#                      shop_url("?message=New+Product+Saved"));
+#        exit;
+#      }
+#    }
+#  }
 
-sub delete_product {
-  my $id = param('id');
-  if ($id and
-     my $product = Products->getByPkey($id)) {
-    $product->{listed} = 0;
-    $product->save();
-    use Util 'generate_article';
-    generate_article('Articles', $product) if $AUTO_GENERATE;
-    shop_redirect("?message=Product+hidden");
-  }
-  else {
-    product_list();
-  }
-}
+#  sub delete_product {
+#    my $id = param('id');
+#    if ($id and
+#       my $product = Products->getByPkey($id)) {
+#      $product->{listed} = 0;
+#      $product->save();
+#      use Util 'generate_article';
+#      generate_article('Articles', $product) if $AUTO_GENERATE;
+#      shop_redirect("?message=Product+hidden");
+#    }
+#    else {
+#      product_list();
+#    }
+#  }
 
-sub undelete_product {
-  my $id = param('id');
-  if ($id and
-     my $product = Products->getByPkey($id)) {
-    $product->{listed} = 1;
-    $product->save();
-    use Util 'generate_article';
-    generate_article('Articles', $product) if $AUTO_GENERATE;
-    shop_redirect("?message=Product+shown");
-  }
-  else {
-    product_list();
-  }
-}
+#  sub undelete_product {
+#    my $id = param('id');
+#    if ($id and
+#       my $product = Products->getByPkey($id)) {
+#      $product->{listed} = 1;
+#      $product->save();
+#      use Util 'generate_article';
+#      generate_article('Articles', $product) if $AUTO_GENERATE;
+#      shop_redirect("?message=Product+shown");
+#    }
+#    else {
+#      product_list();
+#    }
+#  }
 
 sub product_detail {
-  my $id = param('id');
+  my ($req) = @_;
+
+  my $cgi = $req->cgi;
+  my $id = $cgi->param('id');
   if ($id and
       my $product = Products->getByPkey($id)) {
-    product_form($product, '', '', 'product_detail');
+    product_form($req, $product, '', '', 'product_detail');
   }
   else {
-    product_list();
+    product_list($req);
   }
 }
 sub product_form {
-  my ($product, $action, $message, $template) = @_;
-
-  $message ||= param('message') || '';
+  my ($req, $product, $action, $message, $template) = @_;
+  
+  my $cgi = $req->cgi;
+  $message ||= $req->cgi->param('message') || '';
   $template ||= 'add_product';
   my @catalogs;
-  my @work = [ $SHOPID, '' ];
+  my $shopid = $req->cfg->entryErr('articles', 'shop');
+  my @work = [ $shopid, '' ];
   while (@work) {
     my ($parent, $title) = @{shift @work};
 
@@ -535,6 +563,8 @@ sub product_form {
   my %stepcat_targets = map { $_->{id}, $_ } @stepcat_targets;
   my @stepcat_possibles = grep !$stepcat_targets{$_->{id}}, @catalogs;
   my @images;
+  @images = $product->images
+    if $product->{id};
 #    @images = $imageEditor->images()
 #      if $product->{id};
   my $image_index;
@@ -542,8 +572,9 @@ sub product_form {
   my %acts;
   %acts =
     (
-     BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
+     BSE::Util::Tags->basic(\%acts, $cgi, $cfg),
      BSE::Util::Tags->admin(\%acts, $cfg),
+     BSE::Util::Tags->secure($req),
      catalogs => 
      sub {
        return popup_menu(-name=>'parentid',
@@ -553,8 +584,6 @@ sub product_form {
                          -override=>1);
      },
      product => sub { CGI::escapeHTML($product->{$_[0]}) },
-     #date => sub { display_date($product->{$_[0]}) },
-     money => sub { sprintf("%.2f", $product->{$_[0]}/100.0) },
      action => sub { $action },
      message => sub { $message },
      script=>sub { $ENV{SCRIPT_NAME} },
@@ -578,6 +607,8 @@ sub product_form {
      },
      movestepcat =>
      sub {
+       return ''
+        unless $req->user_can(edit_reorder_stepparents => $product),
        my $html = '';
        my $refreshto = CGI::escape($ENV{SCRIPT_NAME}
                                   ."?id=$product->{id}&$template=1#step");
@@ -599,13 +630,6 @@ HTML
                  -values=>[ map $_->{id}, @stepcat_possibles ],
                  -labels=>{ map { $_->{id}, $_->{display}} @catalogs });
      },
-     date =>
-     sub {
-       use BSE::Util::SQL qw/sql_to_date/;
-       my ($func, $args) = split ' ', $_[0], 2;
-       $acts{$func} or return "** unknown function '$func' $args **";
-       display_date($acts{$func}->($args));
-     },
      BSE::Util::Tags->
      make_iterator(\@files, 'file', 'files', \$file_index),
      BSE::Util::Tags->
@@ -615,29 +639,31 @@ HTML
   page($template, \%acts);
 }
 
-sub img_return {
-  if (exists $session{imageid}) {
-    if ($session{imageid}) {
-      param('id', $session{imageid});
-      edit_product();
-    }
-    else {
-      add_product();
-    }
-  }
-  else {
-    product_list(); # something wierd
-  }
-}
+#  sub img_return {
+#    if (exists $session{imageid}) {
+#      if ($session{imageid}) {
+#        param('id', $session{imageid});
+#        edit_product();
+#      }
+#      else {
+#        add_product();
+#      }
+#    }
+#    else {
+#      product_list(); # something wierd
+#    }
+#  }
 
 #####################
 # order management
 
 sub order_list_low {
-  my ($template, $title, @orders) = @_;
+  my ($req, $template, $title, @orders) = @_;
 
-  my $from = param('from');
-  my $to = param('to');
+  my $cgi = $req->cgi;
+
+  my $from = $cgi->param('from');
+  my $to = $cgi->param('to');
   use BSE::Util::SQL qw/now_sqldate sql_to_date date_to_sql/;
   use BSE::Util::Valid qw/valid_date/;
   my $today = now_sqldate();
@@ -657,8 +683,8 @@ sub order_list_low {
   if (defined $from || defined $to) {
     $from ||= '1900-01-01';
     $to ||= '2999-12-31';
-    param('from', sql_to_date($from));
-    param('to', sql_to_date($to));
+    $cgi->param('from', sql_to_date($from));
+    $cgi->param('to', sql_to_date($to));
     $to = $to."Z";
     @orders = grep $from le $_->{orderDate} && $_->{orderDate} le $to,
     @orders;
@@ -670,6 +696,7 @@ sub order_list_low {
     (
      BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
      BSE::Util::Tags->admin(\%acts, $cfg),
+     BSE::Util::Tags->secure($req),
      order=> sub { CGI::escapeHTML($orders_work[$order_index]{$_[0]}) },
      iterate_orders_reset =>
      sub {
@@ -682,11 +709,11 @@ sub order_list_low {
      date => sub { display_date($orders_work[$order_index]{$_[0]}) },
      script => sub { $ENV{SCRIPT_NAME} },
      title => sub { $title },
-     ifHaveParam => sub { defined param($_[0]) },
-     ifParam => sub { param($_[0]) },
+     ifHaveParam => sub { defined $cgi->param($_[0]) },
+     ifParam => sub { $cgi->param($_[0]) },
      cgi => 
      sub { 
-       my $value = param($_[0]);
+       my $value = $cgi->param($_[0]);
        defined $value or $value = '';
        CGI::escapeHTML($value);
      },
@@ -695,39 +722,59 @@ sub order_list_low {
 }
 
 sub order_list {
+  my ($req) = @_;
+
+  $req->user_can('shop_order_list')
+    or return product_list($req, "You don't have access to the order list");
+    
   my $orders = Orders->new;
   my @orders = sort { $b->{orderDate} cmp $a->{orderDate} } $orders->all;
-  my $template = param('template');
+  my $template = $req->cgi->param('template');
   unless (defined $template && $template =~ /^\w+$/) {
     $template = 'order_list';
   }
 
-  order_list_low($template, 'Order list', @orders);
+  order_list_low($req, $template, 'Order list', @orders);
 }
 
 sub order_list_filled {
+  my ($req) = @_;
+
+  $req->user_can('shop_order_list')
+    or return product_list($req, "You don't have access to the order list");
+
   my $orders = Orders->new;
   my @orders = sort { $b->{orderDate} cmp $a->{orderDate} } 
     grep $_->{filled} && $_->{paidFor}, $orders->all;
 
-  order_list_low('order_list_filled', 'Order list - Filled orders', @orders);
+  order_list_low($req, 'order_list_filled', 'Order list - Filled orders', @orders);
 }
 
 sub order_list_unfilled {
+  my ($req) = @_;
+
+  $req->user_can('shop_order_list')
+    or return product_list($req, "You don't have access to the order list");
+
   my $orders = Orders->new;
   my @orders = sort { $b->{orderDate} cmp $a->{orderDate} } 
     grep !$_->{filled} && $_->{paidFor}, $orders->all;
 
-  order_list_low('order_list_unfilled', 'Order list - Unfilled orders', 
+  order_list_low($req, 'order_list_unfilled', 'Order list - Unfilled orders', 
                 @orders);
 }
 
 sub order_list_unpaid {
+  my ($req) = @_;
+
+  $req->user_can('shop_order_list')
+    or return product_list($req, "You don't have access to the order list");
+
   my $orders = Orders->new;
   my @orders = sort { $b->{orderDate} cmp $a->{orderDate} } 
     grep !$_->{paidFor}, $orders->all;
 
-  order_list_low('order_list_unpaid', 'Order list - Incomplete orders', 
+  order_list_low($req, 'order_list_unpaid', 'Order list - Incomplete orders', 
                 @orders);
 }
 
@@ -768,7 +815,13 @@ sub nice_options {
 }
 
 sub order_detail {
-  my $id = param('id');
+  my ($req) = @_;
+
+  $req->user_can('shop_order_detail')
+    or return product_list($req, "You don't have access to order details");
+
+  my $cgi = $req->cgi;
+  my $id = $cgi->param('id');
   if ($id and
       my $order = Orders->getByPkey($id)) {
     my @lines = OrderItems->getBy('orderId', $id);
@@ -782,6 +835,7 @@ sub order_detail {
       (
        BSE::Util::Tags->basic(\%acts, $CGI::Q, $cfg),
        BSE::Util::Tags->admin(\%acts, $cfg),
+       BSE::Util::Tags->secure($req),
        item => sub { CGI::escapeHTML($lines[$line_index]{$_[0]}) },
        iterate_items_reset => sub { $line_index = -1 },
        iterate_items => 
@@ -825,10 +879,15 @@ sub order_detail {
 }
 
 sub order_filled {
-  my $id = param('id');
+  my ($req) = @_;
+
+  $req->user_can('shop_order_filled')
+    or return product_list($req, "You don't have access to order details");
+
+  my $id = $req->cgi->param('id');
   if ($id and
       my $order = Orders->getByPkey($id)) {
-    my $filled = param('filled');
+    my $filled = $req->cgi->param('filled');
     $order->{filled} = $filled;
     if ($order->{filled}) {
       $order->{whenFilled} = epoch_to_sql_datetime(time);
@@ -836,123 +895,123 @@ sub order_filled {
        ? $ENV{REMOTE_USER} : "-unknown-";
     }
     $order->save();
-    if (param('detail')) {
-      order_detail();
+    if ($req->cgi->param('detail')) {
+      order_detail($req);
     }
     else {
-      order_list();
+      order_list($req);
     }
   }
   else {
-    order_list();
+    order_list($req);
   }
 }
 
 #####################
 # Step parents
 
-sub add_stepcat {
-  require 'BSE/Admin/StepParents.pm';
-  my $productid = param('id');
-  defined($productid)
-    or return product_list("No id supplied to add_stepcat");
-  int($productid) eq $productid+0
-    or return product_list("Invalid product id supplied to add_stepcat");
-  my $product = Products->getByPkey($productid)
-    or return product_list("Cannot find product id $productid");
+#  sub add_stepcat {
+#    require 'BSE/Admin/StepParents.pm';
+#    my $productid = param('id');
+#    defined($productid)
+#      or return product_list("No id supplied to add_stepcat");
+#    int($productid) eq $productid+0
+#      or return product_list("Invalid product id supplied to add_stepcat");
+#    my $product = Products->getByPkey($productid)
+#      or return product_list("Cannot find product id $productid");
   
-  eval {
-    my $catid = param('stepcat');
-    defined($catid)
-      or die "No stepcat supplied to add_stepcat";
-    int($catid) eq $catid
-      or die "Invalid stepcat supplied to add_stepcat";
-    my $catalog = Articles->getByPkey($catid)
-      or die "Catalog $catid not found";
-
-    my $release = param('release');
-    defined $release
-      or $release = "01/01/2000";
-    use BSE::Util::Valid qw/valid_date/;
-    $release eq '' or valid_date($release)
-      or die "Invalid release date";
-    my $expire = param('expire');
-    defined $expire
-      or $expire = '31/12/2999';
-    $expire eq '' or valid_date($expire)
-      or die "Invalid expire data";
+#    eval {
+#      my $catid = param('stepcat');
+#      defined($catid)
+#        or die "No stepcat supplied to add_stepcat";
+#      int($catid) eq $catid
+#        or die "Invalid stepcat supplied to add_stepcat";
+#      my $catalog = Articles->getByPkey($catid)
+#        or die "Catalog $catid not found";
+
+#      my $release = param('release');
+#      defined $release
+#        or $release = "01/01/2000";
+#      use BSE::Util::Valid qw/valid_date/;
+#      $release eq '' or valid_date($release)
+#        or die "Invalid release date";
+#      my $expire = param('expire');
+#      defined $expire
+#        or $expire = '31/12/2999';
+#      $expire eq '' or valid_date($expire)
+#        or die "Invalid expire data";
   
-    my $newentry = 
-      BSE::Admin::StepParents->add($catalog, $product, $release, $expire);
-  };
-  $@ and product_edit_refresh($productid, $@, 'step');
+#      my $newentry = 
+#        BSE::Admin::StepParents->add($catalog, $product, $release, $expire);
+#    };
+#    $@ and product_edit_refresh($productid, $@, 'step');
 
-  return product_edit_refresh($productid, '', 'step');
-}
+#    return product_edit_refresh($productid, '', 'step');
+#  }
 
-sub del_stepcat {
-  require 'BSE/Admin/StepParents.pm';
-  my $productid = param('id');
-  defined $productid
-    or return product_list("No id supplied to del_stepcat");
-  int($productid) eq $productid+0
-    or return product_list("Invalid product id supplied to del_stepcat");
-  my $product = Products->getByPkey($productid)
-    or return product_list("Cannot find product id $productid");
-
-  my $catid = param('stepcat');
-  defined($catid)
-    or return shop_redirect("?id=$productid&edit_product=1&message=No+stepcat+supplied+to+add_stepcat#step");
-  int($catid) eq $catid
-    or return shop_redirect("?id=$productid&edit_product=1&message=Invalid+stepcat+supplied+to+add_stepcat#step");
-  my $catalog = Articles->getByPkey($catid)
-    or return shop_redirect("?id=$productid&edit_product=1&message=".CGI::escape("Catalog+$catid+not+found")."#step");
-
-  eval {
-    BSE::Admin::StepParents->del($catalog, $product);
-  };
-  $@ and return shop_redirect("?id=$productid&edit_product=1&message=".CGI::escape($@)."#step");
-
-  return shop_redirect("?id=$productid&edit_product=1#step");
-}
+#  sub del_stepcat {
+#    require 'BSE/Admin/StepParents.pm';
+#    my $productid = param('id');
+#    defined $productid
+#      or return product_list("No id supplied to del_stepcat");
+#    int($productid) eq $productid+0
+#      or return product_list("Invalid product id supplied to del_stepcat");
+#    my $product = Products->getByPkey($productid)
+#      or return product_list("Cannot find product id $productid");
+
+#    my $catid = param('stepcat');
+#    defined($catid)
+#      or return shop_redirect("?id=$productid&edit_product=1&message=No+stepcat+supplied+to+add_stepcat#step");
+#    int($catid) eq $catid
+#      or return shop_redirect("?id=$productid&edit_product=1&message=Invalid+stepcat+supplied+to+add_stepcat#step");
+#    my $catalog = Articles->getByPkey($catid)
+#      or return shop_redirect("?id=$productid&edit_product=1&message=".CGI::escape("Catalog+$catid+not+found")."#step");
+
+#    eval {
+#      BSE::Admin::StepParents->del($catalog, $product);
+#    };
+#    $@ and return shop_redirect("?id=$productid&edit_product=1&message=".CGI::escape($@)."#step");
+
+#    return shop_redirect("?id=$productid&edit_product=1#step");
+#  }
 
-sub save_stepcats {
-  require 'BSE/Admin/StepParents.pm';
-  my $productid = param('id');
-  defined $productid
-    or return product_list("No id supplied to del_stepcat");
-  int($productid) eq $productid+0
-    or return product_list("Invalid product id supplied to del_stepcat");
-  my $product = Products->getByPkey($productid)
-    or return product_list("Cannot find product id $productid");
-
-  my @stepcats = OtherParents->getBy(childId=>$product->{id});
-  my %stepcats = map { $_->{parentId}, $_ } @stepcats;
-  my %datedefs = ( release => '2000-01-01', expire=>'2999-12-31' );
-  for my $stepcat (@stepcats) {
-    for my $name (qw/release expire/) {
-      my $date = param($name.'_'.$stepcat->{parentId});
-      if (defined $date) {
-       if ($date eq '') {
-         $date = $datedefs{$name};
-       }
-       elsif (valid_date($date)) {
-         use BSE::Util::SQL qw/date_to_sql/;
-         $date = date_to_sql($date);
-       }
-       else {
-         product_edit_refresh($productid, "Invalid date '$date'");
-       }
-       $stepcat->{$name} = $date;
-      }
-    }
-    eval {
-      $stepcat->save();
-    };
-    $@ and product_edit_refresh($productid, $@);
-  }
-  product_edit_refresh($productid, $@);
-}
+#  sub save_stepcats {
+#    require 'BSE/Admin/StepParents.pm';
+#    my $productid = param('id');
+#    defined $productid
+#      or return product_list("No id supplied to del_stepcat");
+#    int($productid) eq $productid+0
+#      or return product_list("Invalid product id supplied to del_stepcat");
+#    my $product = Products->getByPkey($productid)
+#      or return product_list("Cannot find product id $productid");
+
+#    my @stepcats = OtherParents->getBy(childId=>$product->{id});
+#    my %stepcats = map { $_->{parentId}, $_ } @stepcats;
+#    my %datedefs = ( release => '2000-01-01', expire=>'2999-12-31' );
+#    for my $stepcat (@stepcats) {
+#      for my $name (qw/release expire/) {
+#        my $date = param($name.'_'.$stepcat->{parentId});
+#        if (defined $date) {
+#      if ($date eq '') {
+#        $date = $datedefs{$name};
+#      }
+#      elsif (valid_date($date)) {
+#        use BSE::Util::SQL qw/date_to_sql/;
+#        $date = date_to_sql($date);
+#      }
+#      else {
+#        product_edit_refresh($productid, "Invalid date '$date'");
+#      }
+#      $stepcat->{$name} = $date;
+#        }
+#      }
+#      eval {
+#        $stepcat->save();
+#      };
+#      $@ and product_edit_refresh($productid, $@);
+#    }
+#    product_edit_refresh($productid, $@);
+#  }
 
 #####################
 # utilities
index 865da5f..22643c1 100755 (executable)
@@ -1,54 +1,58 @@
 #!/usr/bin/perl -w
+# -d:ptkdb
+BEGIN { $ENV{DISPLAY} = '192.168.32.15:0.0' }
+
 use strict;
 use FindBin;
 use lib "$FindBin::Bin/../modules";
 use BSE::SubscriptionTypes;
-use CGI;
 use BSE::DB;
-use BSE::Cfg;
-use BSE::Session;
 use BSE::Util::Tags;
 use BSE::Template;
 use Constants qw($TMPLDIR);
 use Articles;
 use Util qw/refresh_to/;
 use BSE::Message;
+use BSE::Permissions;
+use BSE::Request;
 
-my $cfg = BSE::Cfg->new;
-my %session;
-BSE::Session->tie_it(\%session, $cfg);
-
-my %steps =
-  (
-   list => \&list,
-   add => \&add,
-   addsave => \&addsave,
-   edit => \&edit,
-   editsave => \&editsave,
-   start_send => \&start_send,
-   send_form => \&send_form,
-   html_preview => \&html_preview,
-   text_preview => \&text_preview,
-   send => \&send_message,
-  );
-
-my $q = CGI->new;
-my $action = 'list';
-for my $name (keys %steps) {
-  if ($q->param($name)) {
-    $action = $name;
-    last;
+my $req = BSE::Request->new;
+if (BSE::Permissions->check_logon($req)) {
+  my $cfg = $req->cfg;
+  
+  my %steps =
+    (
+     list => \&list,
+     add => \&add,
+     addsave => \&addsave,
+     edit => \&edit,
+     editsave => \&editsave,
+     start_send => \&start_send,
+     send_form => \&send_form,
+     html_preview => \&html_preview,
+     text_preview => \&text_preview,
+     send => \&send_message,
+    );
+  
+  my $q = $req->cgi;
+  my $action = 'list';
+  for my $name (keys %steps) {
+    if ($q->param($name)) {
+      $action = $name;
+      last;
+    }
   }
+  
+  $steps{$action}->($q, $req, $cfg);
+}
+else {
+  refresh_to($req->url('logon'));
 }
-
-$steps{$action}->($q, \%session, $cfg);
-
-untie %session;
 
 sub list {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg, $message) = @_;
 
-  my $message = $q->param('m') || '';
+  $message ||= $q->param('m') || '';
   my @subs = sort { lc $a->{name} cmp $b->{name} } BSE::SubscriptionTypes->all;
   my $subindex;
   my %acts;
@@ -57,6 +61,7 @@ sub list {
      BSE::Util::Tags->basic(\%acts, $q, $cfg),
      BSE::Util::Tags->make_iterator(\@subs, 'subscription', 'subscriptions',
                                    \$subindex),
+     BSE::Util::Tags->secure($req),
      message => sub { CGI::escapeHTML($message) },
     );
   BSE::Template->show_page('admin/subs/list', $cfg, \%acts);
@@ -111,7 +116,7 @@ sub _parent_popup {
 }
 
 sub sub_form {
-  my ($q, $session, $cfg, $template, $sub, $old, $errors) = @_;
+  my ($q, $req, $cfg, $template, $sub, $old, $errors) = @_;
 
   my %defs = ( archive => 1, visible => 1 );
 
@@ -160,9 +165,12 @@ sub sub_form {
 }
 
 sub add {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_add')
+    or return list($q, $req, $cfg, "You dont have access to add subscriptions");
 
-  sub_form($q, $session, $cfg, 'admin/subs/add', undef, 0);
+  sub_form($q, $req, $cfg, 'admin/subs/add', undef, 0);
 }
 
 sub validate {
@@ -208,7 +216,10 @@ sub _refresh_list {
 }
 
 sub addsave {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_add')
+    or return list($q, $req, $cfg, "You dont have access to add subscriptions");
 
   my @errors;
   if (validate($q, $cfg, \@errors)) {
@@ -225,22 +236,31 @@ sub addsave {
     _refresh_list($cfg);  
   }
   else {
-    sub_form($q, $session, $cfg, 'admin/subs/add', undef, 1, \@errors);
+    sub_form($q, $req, $cfg, 'admin/subs/add', undef, 1, \@errors);
   }
 }
 
 sub edit {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_edit')
+    or return list($q, $req, $cfg, "You dont have access to edit subscriptions");
 
   my $id = $q->param('id')
     or return _refresh_list($cfg, "No id supplied to be edited");
+
+
   my $sub = BSE::SubscriptionTypes->getByPkey($id)
     or return _refresh_list($cfg, "Cannot find record $id");
-  sub_form($q, $session, $cfg, 'admin/subs/edit', $sub, 0);
+
+  sub_form($q, $req, $cfg, 'admin/subs/edit', $sub, 0);
 }
 
 sub editsave {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_edit')
+    or return list($q, $req, $cfg, "You dont have access to edit subscriptions");
 
   my $id = $q->param('id')
     or return _refresh_list($cfg, "No id supplied to be edited");
@@ -259,12 +279,15 @@ sub editsave {
     _refresh_list($cfg);
   }
   else {
-    sub_form($q, $session, $cfg, 'admin/subs/edit', $sub, 1, \@errors);
+    sub_form($q, $req, $cfg, 'admin/subs/edit', $sub, 1, \@errors);
   }
 }
 
 sub start_send {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_send')
+    or return list($q, $req, $cfg, "You dont have access to send subscriptions");
 
   my $msgs = BSE::Message->new(cfg=>$cfg, section=>'subs');
   my $id = $q->param('id')
@@ -281,7 +304,10 @@ sub start_send {
 }
 
 sub send_form {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_send')
+    or return list($q, $req, $cfg, "You dont have access to send subscriptions");
 
   my $msgs = BSE::Message->new(cfg=>$cfg, section=>'subs');
   my $id = $q->param('id')
@@ -304,7 +330,10 @@ sub send_form {
 }
 
 sub html_preview {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_send')
+    or return list($q, $req, $cfg, "You dont have access to send subscriptions");
 
   my $msgs = BSE::Message->new(cfg=>$cfg, section=>'subs');
   my $id = $q->param('id')
@@ -371,7 +400,10 @@ sub _dummy_user {
 }
 
 sub text_preview {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_send')
+    or return list($q, $req, $cfg, "You dont have access to send subscriptions");
 
   my $msgs = BSE::Message->new(cfg=>$cfg, section=>'subs');
   my $id = $q->param('id')
@@ -404,7 +436,10 @@ sub _first {
 }
 
 sub send_message {
-  my ($q, $session, $cfg) = @_;
+  my ($q, $req, $cfg) = @_;
+
+  $req->user_can('subs_send')
+    or return list($q, $req, $cfg, "You dont have access to send subscriptions");
 
   my $msgs = BSE::Message->new(cfg=>$cfg, section=>'subs');
   my $id = $q->param('id')
index 51ffb85..3555ff9 100644 (file)
@@ -131,7 +131,7 @@ descendants=1
 
 [permission change_body]
 help=The user only has permission to change the body of the article or product.
-permissions=edit_field_body
+permissions=edit_field_edit_body,edit_field_edit_title,edit_save
 brief=Change body
 
 [permission shop_access]
index 5123c77..f2c4e40 100644 (file)
@@ -101,6 +101,13 @@ EOS
    getArticleFileByArticleId =>
    'select * from article_files where articleId = ? order by displayOrder desc',
    getArticleFileByPkey => 'select * from article_files where id = ?',
+
+   orderFiles =><<SQL,
+select distinct af.*, oi.id as item_id
+from article_files af, order_item oi
+where af.articleId = oi.productId and oi.orderId = ?
+order by af.description
+SQL
    
    getSiteUserByUserId =>
    'select * from site_users where userId = ?',
index 9d9da20..944cac3 100644 (file)
@@ -646,7 +646,10 @@ sub tag_if_children {
 }
 
 sub tag_movechild {
-  my ($self, $kids, $rindex) = @_;
+  my ($self, $req, $article, $kids, $rindex) = @_;
+
+  $req->user_can('edit_reorder_children', $article)
+    or return '';
 
   $$rindex >=0 && $$rindex < @$kids
     or return '** movechild can only be used in the children iterator **';
@@ -695,7 +698,10 @@ sub tag_edit_link {
 }
 
 sub tag_imgmove {
-  my ($article, $rindex, $images) = @_;
+  my ($req, $article, $rindex, $images) = @_;
+
+  $req->user_can(edit_images_reorder => $article)
+    or return '';
 
   $$rindex >= 0 && $$rindex < @$images 
     or return '** imgmove can only be used in image iterator **';
@@ -723,7 +729,10 @@ HTML
 }
 
 sub tag_movefiles {
-  my ($self, $article, $files, $rindex) = @_;
+  my ($self, $req, $article, $files, $rindex) = @_;
+
+  $req->user_can('edit_files_reorder', $article)
+    or return '';
 
   my $html = '';
 
@@ -797,12 +806,16 @@ sub iter_admin_groups {
 sub tag_if_field_perm {
   my ($req, $article, $field) = @_;
 
-  $field =~ /^\w+$/ or return;
+  unless ($field =~ /^\w+$/) {
+    print STDERR "Bad fieldname '$field'\n";
+    return;
+  }
   if ($article->{id}) {
-    return 1;
+    return $req->user_can("edit_field_edit_$field", $article);
   }
   else {
-    return $req->user_can("edit_field_edit_$field", $article);
+    print STDERR "adding, always successful\n";
+    return 1;
   }
 }
 
@@ -841,6 +854,18 @@ sub low_edit_tags {
 
     $msg = join "<br>", @out, values %work;
   }
+  my $parent;
+  if ($article->{id}) {
+    if ($article->{parentid} > 0) {
+      $parent = $article->parent;
+    }
+    else {
+      $parent = { title=>"No parent - this is a section", id=>-1 };
+    }
+  }
+  else {
+    $parent = { title=>"How did we get here?", id=>0 };
+  }
   my @images;
   my $image_index;
   my @children;
@@ -874,7 +899,7 @@ sub low_edit_tags {
      DevHelp::Tags->make_iterator2
      ([ \&iter_get_images, $article ], 'image', 'images', \@images, 
       \$image_index),
-     imgmove => [ \&tag_imgmove, $article, \$image_index, \@images ],
+     imgmove => [ \&tag_imgmove, $request, $article, \$image_index, \@images ],
      message => $msg,
      DevHelp::Tags->make_iterator2
      ([ \&iter_get_kids, $article, $articles ], 
@@ -882,7 +907,8 @@ sub low_edit_tags {
      ifchildren => \&tag_if_children,
      childtype => [ \&tag_art_type, $article->{level}+1, $cfg ],
      ifHaveChildType => [ \&tag_if_have_child_type, $article->{level}, $cfg ],
-     movechild => [ \&tag_movechild, $self, \@children, \$child_index],
+     movechild => [ \&tag_movechild, $self, $request, $article, \@children, 
+                   \$child_index],
      is => \&tag_is,
      templates => [ \&tag_templates, $self, $article, $cfg, $cgi ],
      titleImages => [ \&tag_title_images, $self, $article, $cfg, $cgi ],
@@ -919,7 +945,8 @@ sub low_edit_tags {
        \@stepparent_targs, \@stepparentpossibles, ],
      DevHelp::Tags->make_iterator2
      ([ \&iter_files, $article ], 'file', 'files', \@files, \$file_index ),
-     movefiles => [ \&tag_movefiles, $self, $article, \@files, \$file_index ],
+     movefiles => 
+     [ \&tag_movefiles, $self, $request, $article, \@files, \$file_index ],
      DevHelp::Tags->make_iterator2
      (\&iter_admin_users, 'iadminuser', 'adminusers'),
      DevHelp::Tags->make_iterator2
@@ -928,6 +955,7 @@ sub low_edit_tags {
      error => [ \&tag_hash, $errors ],
      error_img => [ \&tag_error_img, $self, $errors ],
      ifFieldPerm => [ \&tag_if_field_perm, $request, $article ],
+     parent => [ \&tag_hash, $parent ],
     );
 }
 
@@ -1186,12 +1214,14 @@ sub save {
   my %data;
   for my $name ($article->columns) {
     $data{$name} = $cgi->param($name) 
-      if defined($cgi->param($name)) and $name ne 'id' && $name ne 'parentid';
+      if defined($cgi->param($name)) and $name ne 'id' && $name ne 'parentid'
+       && $req->user_can("edit_field_edit_$name", $article);
   }
   my %errors;
   $self->validate_old($article, \%data, $articles, \%errors)
     or return $self->edit_form($req, $article, $articles, undef, \%errors);
-  $self->save_thumbnail($cgi, $article, \%data);
+  $self->save_thumbnail($cgi, $article, \%data)
+    if $req->user_can('edit_field_edit_thumbImage', $article);
   $self->fill_old_data($req, $article, \%data);
   if (exists $article->{template} &&
       $article->{template} =~ m|\.\.|) {
@@ -1201,47 +1231,56 @@ sub save {
 
   # reparenting
   my $newparentid = $cgi->param('parentid');
-  if ($newparentid == $article->{parentid}) {
-    # nothing to do
-  }
-  elsif ($newparentid != -1) {
-    print STDERR "Reparenting...\n";
-    my $newparent = $articles->getByPkey($newparentid);
-    if ($newparent) {
-      if ($newparent->{level} != $article->{level}-1) {
-       # the article cannot become a child of itself or one of it's 
-       # children
-       if ($article->{id} == $newparentid 
-           || $self->is_descendant($article->{id}, $newparentid, $articles)) {
-         my $msg = "Cannot become a child of itself or of a descendant";
-         return $self->edit_form($req, $article, $articles, $msg);
+  if ($newparentid && $req->user_can('edit_field_edit_parentid', $article)) {
+    if ($newparentid == $article->{parentid}) {
+      # nothing to do
+    }
+    elsif ($newparentid != -1) {
+      print STDERR "Reparenting...\n";
+      my $newparent = $articles->getByPkey($newparentid);
+      if ($newparent) {
+       if ($newparent->{level} != $article->{level}-1) {
+         # the article cannot become a child of itself or one of it's 
+         # children
+         if ($article->{id} == $newparentid 
+             || $self->is_descendant($article->{id}, $newparentid, $articles)) {
+           my $msg = "Cannot become a child of itself or of a descendant";
+           return $self->edit_form($req, $article, $articles, $msg);
+         }
+         my $shopid = $self->{cfg}->entryErr('articles', 'shop');
+         if ($self->is_descendant($article->{id}, $shopid, $articles)) {
+           my $msg = "Cannot become a descendant of the shop";
+           return $self->edit_form($req, $article, $articles, $msg);
+         }
+         my $msg;
+         $self->reparent($article, $newparentid, $articles, \$msg)
+           or return $self->edit_form($req, $article, $articles, $msg);
        }
-       my $shopid = $self->{cfg}->entryErr('articles', 'shop');
-       if ($self->is_descendant($article->{id}, $shopid, $articles)) {
-         my $msg = "Cannot become a descendant of the shop";
-         return $self->edit_form($req, $article, $articles, $msg);
+       else {
+         # stays at the same level, nothing special
+         $article->{parentid} = $newparentid;
        }
-       my $msg;
-       $self->reparent($article, $newparentid, $articles, \$msg)
-         or return $self->edit_form($req, $article, $articles, $msg);
-      }
-      else {
-       # stays at the same level, nothing special
-       $article->{parentid} = $newparentid;
       }
+      # else ignore it
+    }
+    else {
+      # becoming a section
+      my $msg;
+      $self->reparent($article, -1, $articles, \$msg)
+       or return $self->edit_form($req, $article, $articles, $msg);
     }
-    # else ignore it
-  }
-  else {
-    # becoming a section
-    my $msg;
-    $self->reparent($article, -1, $articles, \$msg)
-      or return $self->edit_form($req, $article, $articles, $msg);
   }
 
-  $article->{listed} = $cgi->param('listed') if defined $cgi->param('listed');
-  $article->{release} = sql_date($cgi->param('release'));
-  $article->{expire} = sql_date($cgi->param('expire')) || $Constants::D_99;
+  $article->{listed} = $cgi->param('listed')
+    if defined $cgi->param('listed') && 
+      $req->user_can('edit_field_edit_listed', $article);
+  $article->{release} = sql_date($cgi->param('release'))
+    if defined $cgi->param('release') && 
+      $req->user_can('edit_field_edit_release', $article);
+  
+  $article->{expire} = sql_date($cgi->param('expire')) || $Constants::D_99
+    if defined $cgi->param('expire') && 
+      $req->user_can('edit_field_edit_expire', $article);
   $article->{lastModified} =  now_sqldate();
   my $link_titles = $self->{cfg}->entryBool('basic', 'link_titles', 0);
   if ($article->{id} != 1 && $article->{link} && $link_titles) {
@@ -1592,6 +1631,10 @@ sub show_images {
 sub save_image_changes {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can(edit_images_save => $article)
+    or return $self->show_images($req, $article, $articles,
+                                "You don't have access to save image information for this article");
+
   my $cgi = $req->cgi;
   my $image_pos = $cgi->param('imagePos');
   if ($image_pos 
@@ -1630,6 +1673,10 @@ sub save_image_changes {
 sub add_image {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can(edit_images_add => $article)
+    or return $self->show_images($req, $article, $articles,
+                                "You don't have access to add new images to this article");
+
   my $cgi = $req->cgi;
 
   my $image = $cgi->param('image');
@@ -1706,6 +1753,10 @@ sub add_image {
 sub remove_img {
   my ($self, $req, $article, $articles, $imageid) = @_;
 
+  $req->user_can(edit_images_delete => $article)
+    or return $self->show_images($req, $article, $articles,
+                                "You don't have access to delete images from this article");
+
   $imageid or die;
 
   my @images = $article->images();
@@ -1721,6 +1772,10 @@ sub remove_img {
 sub move_img_up {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can(edit_images_reorder => $article)
+    or return $self->show_images($req, $article, $articles,
+                                "You don't have access to reorder images in this article");
+
   my $imageid = $req->cgi->param('imageid');
   my @images = $article->images;
   my ($imgindex) = grep $images[$_]{id} == $imageid, 0..$#images
@@ -1739,6 +1794,10 @@ sub move_img_up {
 sub move_img_down {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can(edit_images_reorder => $article)
+    or return $self->show_images($req, $article, $articles,
+                                "You don't have access to reorder images in this article");
+
   my $imageid = $req->cgi->param('imageid');
   my @images = $article->images;
   my ($imgindex) = grep $images[$_]{id} == $imageid, 0..$#images
@@ -1809,6 +1868,10 @@ sub filelist {
 sub fileadd {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can(edit_files_add => $article)
+    or return $self->filelist($req, $article, $articles,
+                             "You don't have access to add files to this article");
+
   my %file;
   my $cgi = $req->cgi;
   require ArticleFile;
@@ -1901,6 +1964,10 @@ sub fileadd {
 sub fileswap {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can('edit_files_reorder', $article)
+    or return $self->filelist($req, $article, $articles,
+                          "You don't have access to reorder files in this article");
+
   my $cgi = $req->cgi;
   my $id1 = $cgi->param('file1');
   my $id2 = $cgi->param('file2');
@@ -1925,6 +1992,10 @@ sub fileswap {
 sub filedel {
   my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can('edit_files_delete', $article)
+    or return $self->filelist($req, $article, $articles,
+                          "You don't have access to delete files from this article");
+
   my $cgi = $req->cgi;
   my $fileid = $cgi->param('file');
   if ($fileid) {
@@ -1951,8 +2022,11 @@ sub filedel {
 }
 
 sub filesave {
-  my ($self, $req, $article) = @_;
+  my ($self, $req, $article, $articles) = @_;
 
+  $req->user_can('edit_files_save', $article)
+    or return $self->filelist($req, $article, $articles,
+                          "You don't have access to save file information for this article");
   my @files = $article->files;
 
   my $cgi = $req->cgi;
@@ -1975,6 +2049,11 @@ sub filesave {
 sub can_remove {
   my ($self, $req, $article, $articles, $rmsg) = @_;
 
+  unless ($req->user_can('edit_delete_article', $article, $rmsg)) {
+    $$rmsg ||= "Access denied";
+    return;
+  }
+
   if ($articles->children($article->{id})) {
     $$rmsg = "This article has children.  You must delete the children first (or change their parents)";
     return;
index 047faa4..c170eb5 100644 (file)
@@ -176,13 +176,34 @@ sub _permname_match {
   return $info->{not} ? !$match : $match;
 }
 
+sub _get_article {
+  my ($self, $id) = @_;
+
+  return $self->{artcache}{$id}
+    if exists $self->{artcache}{$id};
+
+  if ($id == -1) {
+    $self->{sitearticle} ||=
+      {
+       generator=>'Generate::Article',
+       id=>-1,
+       parentid=>0,
+       title=>'The site',
+      };
+    return $self->{sitearticle};
+  }
+  else {
+    require Articles;
+    $self->{artcache}{$id} = Articles->getByPkey($id);
+  }
+}
+
 sub _art_ancestors {
   my ($self, $article) = @_;
 
   my @result;
-  while ($article->{id} > 0 && $article->{parentid} != -1) {
-    $article = $self->{artcache}{$article->{parentid}}
-      || $article->parent;
+  while ($article->{id} && $article->{id} > 0 && $article->{parentid} != -1) {
+    $article = $self->_get_article($article->{parentid});
     push @result, $article;
   }
   if ($article && $article->{parentid} == -1) {
@@ -248,6 +269,11 @@ sub user_has_perm {
   $self->{cfg}->entry('basic', 'access_control', 0)
     or return 1;
 
+  unless (ref $article) {
+    $article = $self->_get_article($article)
+      or return;
+  }
+
   if ($checks{$action}) {
     my $method = "check_$action";
     $self->$method($user, $article, $action, $rmsg)
index d50fcdc..97c56dc 100644 (file)
@@ -1,7 +1,7 @@
 package BSE::Request;
 use strict;
 use BSE::Session;
-use CGI;
+use CGI ();
 use BSE::Cfg;
 
 sub new {
@@ -54,12 +54,36 @@ sub url {
   $url;
 }
 
+sub check_admin_logon {
+  my ($self) = @_;
+
+  require BSE::Permissions;
+  return BSE::Permissions->check_logon($self);
+}
+
+
+my $site_article = { id=>-1, title=>"unknown", parentid=>0 };
+
 sub user_can {
   my ($self, $perm, $object, $rmsg) = @_;
 
-  return 1 unless $self->{user};
+  return 1 unless $self->{adminuser};
   require BSE::Permissions;
   $self->{perms} ||= BSE::Permissions->new($self->cfg);
+  $object ||= $site_article;
+  unless (ref $object) {
+    require Articles;
+    my $art = $object == -1 ? $site_article : Articles->getByPkey($object);
+    if ($art) {
+      $object = $art;
+    }
+    else {
+      print STDERR "** Cannot find article id $object\n";
+      require Carp;
+      Carp::cluck "Cannot find article id $object";
+      return 0;
+    }
+  }
   return $self->{perms}->user_has_perm($self->user, $object, $perm, $rmsg);
 }
 
index 5a683d6..4fd2989 100644 (file)
@@ -474,6 +474,13 @@ sub userpage {
                                 getBy(orderId=>$orders[$_[0]]{id});
                             },
                             'item', 'items', \$item_index),
+     BSE::Util::Tags->
+     make_dependent_iterator(\$order_index,
+                            sub {
+                              @files = BSE::DB->query
+                                (orderFiles=>$orders[$_[0]]{id});
+                            },
+                            'orderfile', 'orderfiles', \$file_index),
      product =>
      sub {
        require 'Products.pm';
index f70653c..5b34e10 100644 (file)
@@ -100,6 +100,22 @@ sub static {
         or die; # leaves if in place
        $left =~ $right;
      },
+     ifOr =>
+     sub {
+       my @args = DevHelp::Tags->get_parms(@_[0,1,3]);
+       for my $item (@args) {
+        return 1 if $item;
+       }
+       return 0;
+     },
+     ifAnd =>
+     sub {
+       my @args = DevHelp::Tags->get_parms(@_[0,1,3]);
+       for my $item (@args) {
+        return 0 unless $item;
+       }
+       return 1;
+     },
      cfg =>
      sub {
        my ($section, $key, $def) = split ' ', $_[0];
@@ -350,6 +366,7 @@ sub tag_if_user_can {
          $article = \%dummy_site_article;
        }
        else {
+         require Articles;
          $article = Articles->getByPkey($artname);
          unless ($article) {
            print STDERR "Could not find article $artname\n";
@@ -365,6 +382,7 @@ sub tag_if_user_can {
              $article = \%dummy_site_article;
            }
            else {
+             require Articles;
              $article = Articles->getByPkey($artid);
            }
            unless ($article) {
index 5bae4ec..ca3cd17 100644 (file)
@@ -317,30 +317,52 @@ sub static {
     );  
 }
 
+# this has been an annoying piece of code
+use constant DEBUG_GET_PARMS => 0;
+
 sub get_parms {
   my ($class, $args, $acts, $templater) = @_;
 
+  my $orig = $args;
+
+  print STDERR "** Entered get_parms -$args-\n" if DEBUG_GET_PARMS;
   my @out;
   while ($args) {
     if ($args =~ s/^\s*\[\s*(\w+)(?:\s+(\S[^\]]*))?\]\s*//) {
       my ($func, $subargs) = ($1, $2);
+      $subargs = '' unless defined $subargs;
       if ($acts->{$func}) {
-       $subargs = '' unless defined $subargs;
-       push(@out, $templater->perform($acts, $func, $subargs));
+       print STDERR "  Evaluating [$func $subargs]\n" if DEBUG_GET_PARMS;
+       my $value = $templater->perform($acts, $func, $subargs);
+       print STDERR "    Result '$value'\n" if DEBUG_GET_PARMS;
+       push(@out, $value);
+      }
+      else {
+       print STDERR "  Unknown function '$func' for '$orig'\n" 
+         if DEBUG_GET_PARMS;
+       if (DEBUG_GET_PARMS) {
+         print STDERR "  Available functions: ", join(",", sort keys %$acts),"\n";
+         
+       }
+       die "ENOIMPL '$func $subargs' in '$orig'\n";
       }
     }
     elsif ($args =~ s/^\s*\"((?:[^\"\\]|\\[\\\"])*)\"\s*//) {
       my $out = $1;
       $out =~ s/\\([\\\"])/$1/g;
+      print STDERR "  Adding quoted string '$out'\n" if DEBUG_GET_PARMS;
       push(@out, $out);
     }
     elsif ($args =~ s/^\s*(\S+)\s*//) {
+      print STDERR "  Adding unquoted string '$1'\n" if DEBUG_GET_PARMS;
       push(@out, $1);
     }
     else {
+      print STDERR "  Left over text '$args'\n" if DEBUG_GET_PARMS;
       last;
     }
   }
+  print STDERR "  Result (",join("|", @out),")\n" if DEBUG_GET_PARMS;
 
   @out;
 }
index 312ce33..6add1e0 100644 (file)
@@ -196,7 +196,8 @@ sub _embed_low {
        print STDERR "Cannot load generator $embed->{generator}: $@\n";
        return "** Cannot load generator $embed->{generator} for article $id **";
       }
-      $gen = $embed->{generator}->new(admin=>$self->{admin}, cfg=>$self->{cfg});
+      $gen = $embed->{generator}->new(admin=>$self->{admin}, cfg=>$self->{cfg},
+                                     request=>$self->{request});
     }
 
     # a rare appropriate use of local
index 26bfd50..691234e 100644 (file)
@@ -186,7 +186,8 @@ sub baseActs {
      # generate buttons for administration (only for admin generation)
      admin=>
      sub {
-       if ($self->{admin}) {
+       if ($self->{admin} && $self->{request}) {
+        my $req = $self->{request};
          my $html = <<HTML;
 <table><tr>
 <td><form action="$CGI_URI/admin/add.pl">
@@ -197,7 +198,8 @@ sub baseActs {
 <input type=submit value="Admin menu">
 </form></td>
 HTML
-         if (exists $level_names{1+$article->{level}}) {
+         if (exists $level_names{1+$article->{level}}
+            && $req->user_can(edit_add_child=>$article)) {
            $html .= <<HTML;
 <td><form action="$CGI_URI/admin/add.pl">
 <input type=submit value="Add $level_names{1+$article->{level}}">
@@ -205,7 +207,7 @@ HTML
 </form></td>
 HTML
         }
-        if (generate_button()) {
+        if (generate_button() && $req->user_can(regen_article=>$article)) {
           $html .= <<HTML;
 <td><form action="$CGI_URI/admin/generate.pl">
 <input type=hidden name=id value="$article->{id}">
index fcc8cc5..9939692 100644 (file)
@@ -48,7 +48,8 @@ sub generate_low {
      ifProducts => sub { @products },
      admin => 
      sub { 
-       if ($self->{admin}) {
+       if ($self->{admin} && $self->{request}) {
+        my $req = $self->{request};
         my $html = <<HTML;
 <table>
 <tr>
@@ -59,22 +60,29 @@ sub generate_low {
 <td><form action="$ADMIN_URI">
 <input type=submit value="Admin menu">
 </form></td>
+HTML
+        if ($req->user_can('edit_add_child', $article)) {
+          $html .= <<HTML;
 <td><form action="$CGI_URI/admin/add.pl">
 <input type=hidden name="parentid" value="$article->{id}">
 <input type=hidden name="type" value="Product">
 <input type=submit value="Add product"></form></td>
+HTML
+         }
+        $html .= <<HTML;
 <td><form action="$CGI_URI/admin/shopadmin.pl">
 <input type=hidden name="product_list" value=1>
 <input type=submit value="Full product list"></form></td>
 HTML
-          if (generate_button()) {
-            $html .= <<HTML;
+        if (generate_button()
+            && $req->user_can(regen_article=>$article)) {
+          $html .= <<HTML;
 <td><form action="$CGI_URI/admin/generate.pl">
 <input type=hidden name=id value="$article->{id}">
 <input type=submit value="Regenerate">
 </form></td>
 HTML
-          }
+        }
         $html .= <<HTML;
 <td><form action="$CGI_URI/admin/admin.pl" target="_blank">
 <input type=submit value="Display">
@@ -117,6 +125,9 @@ HTML
      moveallprod =>
      sub {
        return '' unless $self->{admin};
+       return '' unless $self->{request};
+       return '' 
+        unless $self->{request}->user_can(edit_reorder_children => $article);
        my $html = '';
        my $can_move_up = $allprod_index > 0;
        my $can_move_down = $allprod_index < $#allprods;
index 23c965f..6e992e0 100644 (file)
@@ -14,11 +14,11 @@ sub new {
 sub low_perform {
   my ($self, $acts, $func, $args, $orig) = @_;
 
+  $args = '' unless defined $args;
   my $fmt;
   if ($acts->{_format} && $args =~ s/\|(\S+)\s*$//) {
     $fmt = $1;
   }
-  $args = '' unless defined $args;
 
   if (exists $acts->{$func}) {
     $args =~ s/^\s+|\s+$//g;
@@ -201,7 +201,7 @@ sub replace_template {
           and $template = $wraptext
             or last;
 
-       unless (defined $params) {
+       if (defined $params) {
          while ($params =~ s/^\s*(\w+)\s*=>\s*\"([^\"]+)\"//
                 || $params =~ s/^\s*(\w+)\s*=>\s*([^\s,]+)//) {
            $params{$1} = $2;
index 4cc82d3..360999d 100644 (file)
@@ -168,6 +168,54 @@ For fields that the user doesn't have permission for, either the value
 from the [children of I<parentid>] section, the [level I<level>]
 section, or some default value will be used.
 
+=item *
+
+edit_images_add
+
+edit_images_reorder
+
+edit_images_save
+
+edit_images_delete
+
+=item *
+
+edit_files_reorder
+
+edit_files_add
+
+edit_files_delete
+
+edit_files_save
+
+=item *
+
+edit_reorder_children
+
+edit_reorder_stepparents
+
+=item *
+
+subs_add
+
+subs_edit
+
+=item *
+
+regen_extras
+
+regen_article
+
+regen_all
+
+=item *
+
+shop_order_list
+
+shop_order_detail
+
+shop_order_filled
+
 =back
 
 =head2 User/Group Administration
index ee3438d..8756309 100644 (file)
@@ -10,6 +10,71 @@ Maybe I'll add some other bits here.
 
 =head1 CHANGES
 
+=head2 0.12_12
+
+=over
+
+=item *
+
+mysql_build.pl wasn't cleaning up old tables, and since we use it for
+two different projects, the tables from another project were being
+included.
+
+=item *
+
+annoying and numerous warning from Squirrel::Template eliminated
+
+=item *
+
+change admin.pl to check the admin user is logged on
+
+=item *
+
+change generate.pl to check the admin user is logged on and has the
+access needed to regen
+
+=item *
+
+change move.pl to check the admin user is logged on and has the rights
+to perform the move requested
+
+=item *
+
+change reorder.pl to check the admin user is logged on and has the
+rights to perform the reorder requested
+
+=item *
+
+change shopadmin.pl to check the admin user is logged on and that they
+have the rights needed to perform the requested operation
+
+=item *
+
+change subs.pl to check the admin user is logged on and that they have
+the rights needed to perform the requested operation
+
+=item *
+
+BSE::Permissions::user_has_perms() now accepts an article id,
+simplifying some code
+
+=item *
+
+added orderfiles iterator to the userpage.
+
+=item *
+
+updates to BSE::Edit::Article to only allow movements when the user
+has appropriate rights
+
+=item *
+
+field change permissions
+
+
+
+=back
+
 =head2 0.12_11
 
 =over
index 7391c3f..d03b4a0 100644 (file)
@@ -26,6 +26,8 @@
   <p>The new user's password.</p>
 
 </div>
+
+<div>
 <h2><a name="confirm">Confirm</h2>
 
   <p>Confirm the user's password here.</p>
index 5137345..340b878 100644 (file)
@@ -13,8 +13,9 @@ BSE</title>
   <h2><a 
 name="section">Parent</h2>
 
-  <p>The parent this article will be 
-placed under..</p>
+  <p>The parent section this article will be 
+placed under.</p>
+  <p>Catalogs can be moved to other shop sections by selecting a different parent shop section from this menu.</p>
 
 </div>
 
@@ -22,7 +23,7 @@ placed under..</p>
   <h2><a name="title">Catalog 
 title</h2>
 
-  <p>The title of the catalog.</p>
+  <p>The title of the catalog. (The &#145;title&#146; is indexed by the built-in search engine).</p>
 
 </div>
 
@@ -30,7 +31,7 @@ title</h2>
 <h2><a 
 name="template">Template</h2>
 
-  <p>The template used to present this 
+  <p>The HTML template used to layout the display of this 
 catalog.</p>
 
 </div>
@@ -41,7 +42,7 @@ catalog.</p>
 content of your catalog. There are a number of 
 <a
 href="body.html">tags</a> you can use to markup your article 
-text.</p>
+text. (The &#145;body&#146; is indexed by the built-in search engine).</p>
 
 </div>
 
@@ -68,7 +69,7 @@ accessed via a direct URL to the
 don't want the catalog to appear on your site.</p>
 
   <p><b>Note:</b> 
-Expired catalogs can be found through the search 
+Expired catalogs can be found through the built-in search 
 engine.</p>
 
 </div>
@@ -103,9 +104,10 @@ sub-catalogs will be displayed.</p>
 <h2><a 
 name="keywords">Keywords</h2>
 
-<p>This is a comma-separated list of 
-extra keywords used by the search
+  <p>This is a comma-separated list of 
+extra keywords used by the built-in search
 engine.</p>
+  <p>Keywords only need be explicitly indicated here if this catalog should be indexed under words not already used in the &#145;title&#146; or &#145;body&#146; of this catalog.</p>
 
 </div>
 
@@ -128,6 +130,10 @@ image</h2>
 &lt;:thumbnail:&gt; tag to display a small 
     image for the catalog 
 in menus.</p>
+  <p>To upload a &#145;thumbnail&#146; image, either enter the name of an image on your 
+computer, or use the Browse
+button to select an image  file (Usually 
+with a .GIF, .JPG, .PNG file extension) then remember to update the catalog or it wont be uploaded and saved.</p>
 
 </div>
 
@@ -139,7 +145,7 @@ in menus.</p>
     <p>Images attached to the product. This isn't available 
 until the product has 
     been created.</p>
-    <p>You can modify 
+    <p>You can upload and modify 
 the images by clicking the &quot;Manage Images&quot; link.</p>
  
 </div>
index 008e03a..a23b2d3 100644 (file)
@@ -13,8 +13,9 @@ BSE</title>
 <h2><a 
 name="section">Section</h2>
 
-<p>The section this article will be 
-placed under..</p>
+  <p>The section this article will be 
+placed under.</p>
+  <p>Articles can be moved to other sections by selecting a different parent section from this menu.</p>
 
 </div>
 
@@ -22,27 +23,32 @@ placed under..</p>
 <h2><a 
 name="title">Title</h2>
 
-<p>The title of the 
-article.</p>
-
+  <p>The title of the 
+article.  (The &#145;title&#146; is indexed by the built-in search engine).</p>
+  <div>
+    <h2><a 
+name="titleImage">Title image</h2>
+    <p>The title image will replace the text title &lt;:title:&gt; with an image file.</p>
+    <p>Title images need to be uploaded into the &#145;/images/titles&#146; directory, as yet there is no admin interface to do this (this feature is rarely used).</p>
+  </div>
 </div>
 
 <div>
 <h2><a 
 name="template">Template</h2>
 
-<p>The template used to present this 
+  <p>The HTML template used to layout the display of this 
 article.</p>
 
 </div>
 <div>
 <h2><a name="body">Body</h2>
 
-<p>The 
+  <p>The 
 content of your article.  There are a number of 
 <a
 href="body.html">tags</a> you can use to markup your article 
-text.</p>
+text. (The &#145;body&#146; is indexed by the built-in search engine).</p>
 
 </div>
 
@@ -65,13 +71,13 @@ the article.</p>
 
 <div>
   <h2><a 
-name="expire">Expire date</h2>
+name="expire">Expiry date</h2>
 
 <p>The date from which you don't want 
 the article to appear on your site.</p>
 
-<p><b>Note:</b> Expired 
-articles can be found through the search 
+  <p><b>Note:</b> Expired 
+articles can be found through the built-in search 
 engine.</p>
 
 </div>
@@ -109,9 +115,10 @@ articles will be displayed.</p>
 <h2><a 
 name="keywords">Keywords</h2>
 
-<p>This is a comma-separated list of 
-extra keywords used by the search
+  <p>This is a comma-separated list of 
+extra keywords used by the built-in search
 engine.</p>
+  <p>Keywords only need be explicitly indicated here if this article should be indexed under words not already used in the &#145;title&#146; or &#145;body&#146; of this article.</p>
 
 </div>
 
@@ -134,6 +141,10 @@ image</h2>
 &lt;:thumbnail:&gt; tag to display a small 
     image for the article 
 in menus.</p>
+  <p>To upload a &#145;thumbnail&#146; image, either enter the name of an image on your 
+computer, or use the Browse
+button to select an image  file (Usually 
+with a .GIF, .JPG, .PNG file extension) then remember to update the article or it wont be uploaded and saved.</p>
 
 </div>
 
@@ -145,7 +156,7 @@ name="files">Files</h2>
 isn't available until the product has 
     been created.</p>
  
-<p>You can modify the files by clicking the &quot;Manage Files&quot; 
+    <p>You can upload and modify the files by clicking the &quot;Manage Files&quot; 
 link.</p>
   </div>
   <div>
@@ -154,7 +165,7 @@ link.</p>
 <p>Images attached to the product. This isn't available until the 
 product has 
     been created.</p>
-    <p>You can modify the images 
+    <p>You can upload and modify the images 
 by clicking the &quot;Manage Images&quot; link.</p>
   </div>
  
index 16eb471..299e806 100644 (file)
@@ -45,8 +45,8 @@ entries to the [content types] section of the configuration file.</p>
 <p>If this checkbox is checked then BSE will attempt to make the users
 browser download the file rather than display it.</p>
 
-<p>This can be useful for some types such as PDF files, since
-displaying PDFs can destabilize some browsers.</p>
+  <p>This can be useful for some types such as PDF files, since
+displaying PDFs can destabilise some browsers.</p>
 
 </div>
 
index 510a991..94416f1 100644 (file)
@@ -14,7 +14,7 @@ BSE</title>
 file to add</h2>
 
   <p>Either enter the name of an image on your 
-machine, or use the Browse
+computer, or use the Browse
 button to select an image  file (Usually 
 with a .GIF, .JPG, .PNG file extension).</p>
   <p>Please note that if 
@@ -34,7 +34,7 @@ image</h2>
 
   <p>Image Alt (alternate) text is only displayed when 
 your browser does not display images. Setting Alt text is also 
-helpful for sight impared users who use screen 
+helpful for sight impaired users who use screen 
 readers.</p>
 
 </div>
@@ -51,8 +51,8 @@ URL.</p>
   <h2><a name="position">First image 
 position</h2>
 
-<p>This option positions the first article image, 
-based on this choice BSE attempts to arrange susequent images as 
+  <p>This option positions the first article image, 
+based on this choice BSE attempts to arrange subsequent images as 
 alternately staggered down the page.</p>
 
   <p>Relying on BSE to get 
index afbbb2e..6480fec 100644 (file)
@@ -16,7 +16,7 @@ name="title">Title</h2>
   <p>The name of the product (NB: the title 
 cannot be changed once an order has 
     been placed that includes 
-this product).</p>
+this product). (The &#145;title&#146; is indexed by the built-in search engine).</p>
 
 </div>
 
@@ -36,16 +36,22 @@ name="catalog">Catalog</h2>
 
   <p>The catalog in which this product 
 should be listed.</p>
-
+  <p>Products can be moved to other catalogs by selecting a different parent catalog from this menu.</p>
+  <div>
+    <h2><a 
+name="template">Template</h2>
+    <p>The HTML template used to layout the display of this 
+product.</p>
+  </div>
 </div>
 <div>
 <h2><a 
 name="body">Body</h2>
 
-<p>The content of your article.  There are a 
+  <p>The content of your article.  There are a 
 number of <a
 href="body.html">tags</a> you can use to markup your 
-article text.</p>
+product text. (The &#145;body&#146; is indexed by the built-in search engine).</p>
 
 </div>
 
@@ -110,7 +116,7 @@ product.</p>
 site.</p>
 
   <p><b>Note:</b> Expired products can be found through 
-the search engine.</p>
+the built-in search engine.</p>
 
 </div>
 
@@ -166,6 +172,10 @@ name="thumb">Thumbnail image</h2>
 with the &lt;:thumbnail:&gt; tag to display a small 
     image for 
 the product in menus.</p>
+  <p>To upload a &#145;thumbnail&#146; image, either enter the name of an image on your 
+computer, or use the Browse
+button to select an image  file (Usually 
+with a .GIF, .JPG, .PNG file extension) then remember to update the product or it wont be uploaded and saved.</p>
 
 </div>
 
@@ -177,7 +187,7 @@ name="files">Files</h2>
 isn't available until the product has 
     been created.</p>
   <p>You 
-can modify the files by clicking the &quot;Manage Files&quot; 
+can upload and modify the files by clicking the &quot;Manage Files&quot; 
 link.</p>
 
 </div>
@@ -189,7 +199,7 @@ link.</p>
 <p>Images attached to the product. This isn't available until the 
 product has 
     been created.</p>
-  <p>You can modify the images by 
+  <p>You can upload and modify the images by 
 clicking the &quot;Manage Images&quot; 
 link.</p>
 
diff --git a/site/htdocs/images/admin/checked.gif b/site/htdocs/images/admin/checked.gif
new file mode 100755 (executable)
index 0000000..f7aacaa
Binary files /dev/null and b/site/htdocs/images/admin/checked.gif differ
diff --git a/site/htdocs/images/admin/unchecked.gif b/site/htdocs/images/admin/unchecked.gif
new file mode 100644 (file)
index 0000000..e26fb1d
Binary files /dev/null and b/site/htdocs/images/admin/unchecked.gif differ
index c89963a..985e2e2 100644 (file)
@@ -12,6 +12,7 @@
 <:ifMessage:> 
 <p><b><:message:> </b></p>
 <:or:><:eif:>
+<:if UserCan edit_images_add:>
 <h2>Add new image</h2>
 
 <form method="POST" action="<:script:>" enctype="multipart/form-data">
@@ -55,7 +56,7 @@
     </tr>
   </table>
 </form>
-
+<:or UserCan:><:eif UserCan:>
 
 <form method="post" action="<:script:>" enctype="multipart/form-data">
 <input type="hidden" name="level" value="<: level :>">
           </tr>
           <tr bgcolor="#FFFFFF"> 
             <td valign="top"> 
-              <input type="text" name="alt" value="<: image alt :>" size="32">
+              <:ifUserCan edit_images_save article:><input type="text" name="alt" value="<: image alt :>" size="32"><:or:><: image alt :><:eif:>
             </td>
             <td valign="top" width="50%"> 
-              <input type="text" name="url" value="<: image url :>" size="32">
+              <:ifUserCan edit_images_save article:><input type="text" name="url" value="<: image url :>" size="32"><:or:><: image url :><:eif:>
             </td>
             <td valign="bottom" nowrap> 
-              <b><a href="<:script:>?level=<: level :>&parentid=<: article parentid :>&id=<:article id:>&imgtype=<: articleType :>&removeimg_<: image id :>" onClick="return window.confirm('Are you sure you want to delete this Image')">Delete</a></b>
+              <:ifUserCan edit_images_delete article:><b><a href="<:script:>?level=<: level :>&parentid=<: article parentid :>&id=<:article id:>&imgtype=<: articleType :>&removeimg_<: image id :>" onClick="return window.confirm('Are you sure you want to delete this Image')">Delete</a></b><:or:><:eif:>
 <:imgmove:> </td>
           </tr>
           <: iterator separator images :> 
             <td colspan="3">&nbsp;</td>
           </tr>
           <: iterator end images :> 
+<:ifUserCan edit_images_save article:>
           <tr> 
             <td align="right" bgcolor="#FFFFFF" colspan="3"> 
               <input type="submit" name="process" value="Save changes">
             </td>
+         </tr>
+<:or:><:eif:>
         </table>
 </td>
 </tr>
index 1710b67..d2f619f 100644 (file)
@@ -42,8 +42,8 @@
   </tr>
 </table>
 <:or Products:><:eif Products:>
-<form action="/cgi-bin/admin/add.pl">
-  <p><input type=hidden name=parentid value="<:catalog id:>"><input type=hidden name=type value="Product"><input type=submit name="add_product" value="Add Product"></p></form>
+<:ifUserCan edit_add_child catalog:><form action="/cgi-bin/admin/add.pl">
+  <p><input type=hidden name=parentid value="<:catalog id:>"><input type=hidden name=type value="Product"><input type=submit name="add_product" value="Add Product"></p></form><:or:><:eif:>
 <h4>Sub catalogs</h4>
 <h4><:if Subcats :> <:iterator begin subcats:> </h4>
 <ul>
@@ -53,6 +53,6 @@
 </ul>
 <:iterator end subcats:>
 <:or Subcats:><:eif Subcats:>
-<form action="/cgi-bin/admin/add.pl"><input type=hidden name=type value="Catalog">
-  <input type=hidden name=parentid value="<:catalog id:>"><input type=submit value="Add Sub-catalog"></form>
+<:ifUserCan edit_add_child catalog:><form action="/cgi-bin/admin/add.pl"><input type=hidden name=type value="Catalog">
+  <input type=hidden name=parentid value="<:catalog id:>"><input type=submit value="Add Sub-catalog"></form><:or:><:eif:>
 
index 0251a16..9332741 100644 (file)
 <:ifMessage:> 
 <p><b><:message:></b></p>
 <:or:><:eif:>
-<p>| <a href="/admin/">Admin menu</a> | </p>
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | </p>
+
+<:if Or [iadminuser_count] [iadmingroup_count]:>
+      <form action="/cgi-bin/admin/adminusers.pl">
+  <input type=hidden name=id value="<: article id:>">
+  <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
+  <tr>
+    <td>
+        <table cellpadding="6" cellspacing="1" border="0" width="100%">
+          <tr>
+            <th nowrap>
+
+        <font size=2>Manage access:</font>
+        </th>
+            <td bgcolor="#FFFFFF">
+              <select name=adminid>
+<:iterator begin adminusers:>
+<option value=<:iadminuser id:>>User <:iadminuser logon:>
+<:iterator end adminusers:>
+<:iterator begin admingroups:>
+<option value=<:iadmingroup id:>>Group <:iadmingroup name:>
+<:iterator end admingroups:>
+              </select>
+              <input type=submit name="a_showobjectart" value="Manage">
+      </td>
+            <td bgcolor="#FFFFFF"><:help access manage:>
+        </td>
+          </tr>
+        </table>
+    </td>
+   </tr>
+  </table>
+      </form>
+<br>
+<:or Or:><:eif Or:>
 
 <table><tr><td nowrap><form action="/cgi-bin/admin/adminusers.pl"><font size=2>Manage access: <input type=hidden name=id value="<: article id:>">
 <select name=adminid>
           <th>Listed</th>
           <th nowrap>Modify</th>
         </tr>
+<:if UserCan edit_reorder_children:>
         <tr> 
           <td colspan="4" bgcolor="#FFFFFF">Reorder child articles: <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=title&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             title</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=date&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             date</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&reverse=1&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">reverse 
             order</a></td>
         </tr>
+<:or UserCan:><:eif UserCan:>
         <:iterator begin children:> 
         <tr bgcolor="#FFFFFF"> 
           <td width="30%"><a href="<:child admin:>"><:child title:></a></td>
           <td width="70%"><: summary child body :></td>
           <td bgcolor="#FFFFFF" align="center"><: is child listed :></td>
           <td nowrap> <a href="/cgi-bin/admin/add.pl?id=<:child id:>">Edit</a> 
-            <a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this Section')">Delete</a> 
+            <:if UserCan edit_delete_article child:><a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this Section')">Delete</a> <:or UserCan:><:eif UserCan:>
             <:movechild:> </td>
         </tr>
         <:iterator separator children:> <:iterator end children:> 
index 4c964f3..3ff5fd4 100644 (file)
@@ -14,7 +14,7 @@
 <:ifMessage:> 
 <p><b><:message:></b></p>
 <:or:><:eif:>
-<p>| <a href="/admin/">Admin menu</a> | <:ifnew:><:or:><:if Eq [article id] 3:><a href="<:article admin:>">See 
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <:ifnew:><:or:><:if Eq [article id] 3:><a href="<:article admin:>">See 
   shop</a><:or Eq:><a href="<:article admin:>">See article</a><:eif Eq:> | <:eif:><:editParent:> 
   <:if Eq [article id] 3:><a href="/cgi-bin/admin/shopadmin.pl">Manage catalogs</a> 
   |<:or Eq:><:eif Eq:><:if new:><:or new:> <a href="<:script:>?id=<:article id:>&_t=steps">Manage 
   <h2><:articleType:> Details</h2>
 
 <:ifnew:><:or:>
-<table><tr><td nowrap><form action="/cgi-bin/admin/adminusers.pl"><font size=2>Manage access: <input type=hidden name=id value="<: article id:>">
-<select name=adminid>
+<:if Or [iadminuser_count] [iadmingroup_count]:>
+      <form action="/cgi-bin/admin/adminusers.pl">
+  <input type=hidden name=id value="<: article id:>">
+  <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
+  <tr>
+    <td>
+        <table cellpadding="6" cellspacing="1" border="0" width="100%">
+          <tr>
+            <th nowrap>
+
+        <font size=2>Manage access:</font>
+        </th>
+            <td bgcolor="#FFFFFF">
+              <select name=adminid>
 <:iterator begin adminusers:>
 <option value=<:iadminuser id:>>User <:iadminuser logon:>
 <:iterator end adminusers:>
 <:iterator begin admingroups:>
 <option value=<:iadmingroup id:>>Group <:iadmingroup name:>
 <:iterator end admingroups:>
-</select><input type=submit name="a_showobjectart" value="Manage">
-</font></form></td></tr></table><:eif:>
-
+              </select>
+              <input type=submit name="a_showobjectart" value="Manage">
+      </td>
+            <td bgcolor="#FFFFFF"><:help access manage:>
+        </td>
+          </tr>
+        </table>
+    </td>
+   </tr>
+  </table>
+      </form>
+<br>
+<:or Or:><:eif Or:>
+<:eif:>
   <form enctype="multipart/form-data" method="POST" action="<:script:>">
 
     <input type="hidden" name="level" value="<: level :>">
@@ -47,9 +70,9 @@
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> <:parentType:>: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <select name="parentid">
+              <:if FieldPerm parentid:><select name="parentid">
                 <option value="">Please select a <:parentType:><: list:>
-              </select>
+              </select><:or FieldPerm:><:parent title:> (<:parent id:>)<:eif FieldPerm:>
             </td>
             <td bgcolor="#FFFFFF"><:help edit section:> </td>
           </tr>
             <th nowrap bgcolor="#FFFFFF" align="left"> <:articleType:> title: 
             </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="title" maxlength="<:cfg fields title_size 255:>" size="64" value="<: article title :>">
+              <:ifFieldPerm title:><input type="text" name="title" maxlength="<:cfg fields title_size 255:>" size="64" value="<: article title :>"><:or:><:default title:><:eif:>
             </td>
             <td bgcolor="#FFFFFF"><:help edit title:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Title image: </th>
-            <td bgcolor="#FFFFFF" width="100%"> <:titleImages:> (upload this to 
-              the /images/titles directory)</td>
-            <td bgcolor="#FFFFFF">&nbsp;</td>
+            <td bgcolor="#FFFFFF" width="100%"><:ifFieldPerm titleImage:><:titleImages:> (upload this to 
+              the /images/titles directory)<:or:><:article titleImage:><:eif:></td>
+            <td bgcolor="#FFFFFF"><:help edit titleImage:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Template: </th>
-            <td bgcolor="#FFFFFF" width="100%"> <:templates:> </td>
+            <td bgcolor="#FFFFFF" width="100%"><:ifFieldPerm template:> <:templates:><:or:><:article template:><:eif:> </td>
             <td bgcolor="#FFFFFF"><:help edit template:> </td>
           </tr>
           <tr> 
             <th valign="top" nowrap bgcolor="#FFFFFF" align="left"> Body: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea>
+              <:ifFieldPerm body:><textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea><:or:><:bodytext article body:><:eif:>
             </td>
             <td bgcolor="#FFFFFF" valign="top"><:help body body:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Release date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
-              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)</td>
+              <:if FieldPerm release:><input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
+              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)<:or FieldPerm:><: date "%d/%m/%Y" article release :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit release:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Expiry date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
+              <:if FieldPerm expire:><input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
               (dd/mm/yyyy - <: ifnew :>default is never, <: or :><: eif :>blank 
-              for never expires)</td>
+              for never expires)<:or FieldPerm:><: date "%d/%m/%Y" article expire :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit expire:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Summary length: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
+              <:if FieldPerm summaryLength:><input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
               (in characters - <: ifnew :>default inherited from <:parentType:>, <: or :><: eif :> 
-              zero for no summary)</td>
+              zero for no summary)<:or FieldPerm:><: article summaryLength :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit summary:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Display threshold: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>">
+              <:ifFieldPerm threshold:><input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>"><:or:><: article threshold :><:eif:>
             </td>
             <td bgcolor="#FFFFFF"><:help edit threshold:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Keywords: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>">
-              (comma separated)</td>
+              <:ifFieldPerm keyword:><input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>">
+              (comma separated)<:or:><: article threshold :><:eif:></td>
             <td bgcolor="#FFFFFF"><:help edit keywords:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left">List article:</th>
-            <td bgcolor="#FFFFFF" width="100%"> <:list listed:> </td>
+            <td bgcolor="#FFFFFF" width="100%"> <:if FieldPerm listed:><:list listed:><:or FieldPerm:><:if Article listed:><:ifEq [article listed] "1":>Yes<:or:>In Sections, but not menu<:eif:><:or Article:>No<:eif Article:><:eif FieldPerm:> </td>
             <td bgcolor="#FFFFFF"><:help edit listed:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left" valign="top">Thumbnail image:</th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type=file name=thumbnail>
+              <:ifFieldPerm thumbImage:><input type=file name=thumbnail><:or:><:eif:>
               <:ifArticle thumbImage:><img src="/images/<:article thumbImage:>"> 
-              <input type=checkbox name="remove_thumb">
-              Remove<:or:><:eif:></td>
+              <:if FieldPerm thumbImage:><input type=checkbox name="remove_thumb">
+              Remove<:or FieldPerm:><:eif FieldPerm:><:or:><:eif:></td>
             <td bgcolor="#FFFFFF" valign="top"><:help edit thumb:></td>
           </tr>
           <:if Article id:> 
             <th nowrap bgcolor="#FFFFFF" align="left" valign="top"><a name="files"></a>Files:</th>
             <td nowrap bgcolor="#FFFFFF" width="100%"> <:if Files:> 
               <table cellpadding="0" cellspacing="0" border="0" bgcolor="#333333">
-                <tr><td> 
+                <tr>
+                  <td> 
                     <table cellpadding="5" cellspacing="1" border="0">
                       <tr bgcolor="#FFFFFF"> 
                         <th>Filename</th>
                       </tr>
                       <:iterator end files:> 
                     </table>
-              </td></tr></table>
+                  </td>
+                </tr>
+              </table>
               <p><a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a>
               </p>
               <:or Files:>
-              <p>No files are attached to this article. <a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a></p><:eif Files:>
+              <p>No files are attached to this article. <a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a></p>
+              <:eif Files:>
             </td>
             <td nowrap bgcolor="#FFFFFF" valign="top"><:help edit files:></td>
           </tr>
               <hr noshade size="1">
               <: iterator end images :>
               <p align="left"><a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
-             <:or Images:><p align="left">No images are attached to this article.  <a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
-             <:eif Images:>
+              <:or Images:>
+              <p align="left">No images are attached to this article.  <a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
+              <:eif Images:>
            </td>
             <td bgcolor="#FFFFFF" valign="top"><:help edit images:> </td>
           </tr>
 </tr>
 </table>
 
-  <p>
-    <input type="submit" name="save"
-           value="  <: ifnew :>Add New<: or :>Update<: eif :> <: articleType :>  "></p>
+  <p><: ifnew :>
+    <input type="submit" name="save" value="  Add New <: articleType:>  ">
+   <:or:>
+  <:if UserCan edit_save article:><input type="submit" name="save" value="  Update <: articleType:>  "><:or UserCan:><:eif UserCan:>
+   <:eif:></p>
   </form>
 <:if children:> <:ifEq [article id] 3:> 
 <h2>Catalogs</h2>
           <th>Listed</th>
           <th nowrap>Modify</th>
         </tr>
+<:if UserCan edit_reorder_children:>
         <tr> 
           <td colspan="4" bgcolor="#FFFFFF">Reorder child articles: <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=title&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             title</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=date&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             date</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&reverse=1&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">reverse 
             order</a></td>
         </tr>
+<:or UserCan:><:eif UserCan:>
         <:iterator begin children:> 
         <tr bgcolor="#FFFFFF"> 
           <td width="30%"><a href="<:child admin:>"><:child title:></a></td>
           <td width="70%"><: summary child body :></td>
           <td align="center"><: is child listed :></td>
           <td nowrap> <a href="/cgi-bin/admin/add.pl?id=<:child id:>">Edit</a> 
-            <a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>')">Delete</a> 
+            <:if UserCan edit_delete_article child:><a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>')">Delete</a><:or UserCan:><:eif UserCan:>
             <:movechild:> </td>
         </tr>
         <:iterator separator children:> <:iterator end children:> 
 <:if HaveChildType:>
 <:if new:>
 <:or new:>
-<form action="/cgi-bin/admin/add.pl">
+<:if UserCan edit_add_child article:><form action="/cgi-bin/admin/add.pl">
 <input type=hidden name="parentid" value="<:article id:>">
   <p> 
     <input type=submit value="Add <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>">
   </p>
-</form>
+</form><:or UserCan:><:eif UserCan:>
 <:eif new:> <:or HaveChildType:> <:eif HaveChildType:>
 <p><font size="-1">BSE Release <:release:></font></p>
 </body></html>
index 55aa3d7..3ff5fd4 100644 (file)
@@ -14,7 +14,7 @@
 <:ifMessage:> 
 <p><b><:message:></b></p>
 <:or:><:eif:>
-<p>| <a href="/admin/">Admin menu</a> | <:ifnew:><:or:><:if Eq [article id] 3:><a href="<:article admin:>">See 
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <:ifnew:><:or:><:if Eq [article id] 3:><a href="<:article admin:>">See 
   shop</a><:or Eq:><a href="<:article admin:>">See article</a><:eif Eq:> | <:eif:><:editParent:> 
   <:if Eq [article id] 3:><a href="/cgi-bin/admin/shopadmin.pl">Manage catalogs</a> 
   |<:or Eq:><:eif Eq:><:if new:><:or new:> <a href="<:script:>?id=<:article id:>&_t=steps">Manage 
   <h2><:articleType:> Details</h2>
 
 <:ifnew:><:or:>
-<table><tr><td nowrap><form action="/cgi-bin/admin/adminusers.pl"><font size=2>Manage access: <input type=hidden name=id value="<: article id:>">
-<select name=adminid>
+<:if Or [iadminuser_count] [iadmingroup_count]:>
+      <form action="/cgi-bin/admin/adminusers.pl">
+  <input type=hidden name=id value="<: article id:>">
+  <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
+  <tr>
+    <td>
+        <table cellpadding="6" cellspacing="1" border="0" width="100%">
+          <tr>
+            <th nowrap>
+
+        <font size=2>Manage access:</font>
+        </th>
+            <td bgcolor="#FFFFFF">
+              <select name=adminid>
 <:iterator begin adminusers:>
 <option value=<:iadminuser id:>>User <:iadminuser logon:>
 <:iterator end adminusers:>
 <:iterator begin admingroups:>
 <option value=<:iadmingroup id:>>Group <:iadmingroup name:>
 <:iterator end admingroups:>
-</select><input type=submit name="a_showobjectart" value="Manage">
-</font></form></td></tr></table><:eif:>
-
+              </select>
+              <input type=submit name="a_showobjectart" value="Manage">
+      </td>
+            <td bgcolor="#FFFFFF"><:help access manage:>
+        </td>
+          </tr>
+        </table>
+    </td>
+   </tr>
+  </table>
+      </form>
+<br>
+<:or Or:><:eif Or:>
+<:eif:>
   <form enctype="multipart/form-data" method="POST" action="<:script:>">
 
     <input type="hidden" name="level" value="<: level :>">
@@ -47,9 +70,9 @@
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> <:parentType:>: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <:ifFieldPerm parentid:><select name="parentid">
+              <:if FieldPerm parentid:><select name="parentid">
                 <option value="">Please select a <:parentType:><: list:>
-              </select><:or:><input type=hidden name=parentid value=<:article parentid:><:eif:>
+              </select><:or FieldPerm:><:parent title:> (<:parent id:>)<:eif FieldPerm:>
             </td>
             <td bgcolor="#FFFFFF"><:help edit section:> </td>
           </tr>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Title image: </th>
-            <td bgcolor="#FFFFFF" width="100%"> <:titleImages:> (upload this to 
-              the /images/titles directory)</td>
-            <td bgcolor="#FFFFFF">&nbsp;</td>
+            <td bgcolor="#FFFFFF" width="100%"><:ifFieldPerm titleImage:><:titleImages:> (upload this to 
+              the /images/titles directory)<:or:><:article titleImage:><:eif:></td>
+            <td bgcolor="#FFFFFF"><:help edit titleImage:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Template: </th>
-            <td bgcolor="#FFFFFF" width="100%"> <:templates:> </td>
+            <td bgcolor="#FFFFFF" width="100%"><:ifFieldPerm template:> <:templates:><:or:><:article template:><:eif:> </td>
             <td bgcolor="#FFFFFF"><:help edit template:> </td>
           </tr>
           <tr> 
             <th valign="top" nowrap bgcolor="#FFFFFF" align="left"> Body: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea>
+              <:ifFieldPerm body:><textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea><:or:><:bodytext article body:><:eif:>
             </td>
             <td bgcolor="#FFFFFF" valign="top"><:help body body:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Release date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
-              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)</td>
+              <:if FieldPerm release:><input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
+              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)<:or FieldPerm:><: date "%d/%m/%Y" article release :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit release:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Expiry date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
+              <:if FieldPerm expire:><input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
               (dd/mm/yyyy - <: ifnew :>default is never, <: or :><: eif :>blank 
-              for never expires)</td>
+              for never expires)<:or FieldPerm:><: date "%d/%m/%Y" article expire :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit expire:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Summary length: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
+              <:if FieldPerm summaryLength:><input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
               (in characters - <: ifnew :>default inherited from <:parentType:>, <: or :><: eif :> 
-              zero for no summary)</td>
+              zero for no summary)<:or FieldPerm:><: article summaryLength :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help edit summary:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Display threshold: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>">
+              <:ifFieldPerm threshold:><input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>"><:or:><: article threshold :><:eif:>
             </td>
             <td bgcolor="#FFFFFF"><:help edit threshold:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left"> Keywords: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>">
-              (comma separated)</td>
+              <:ifFieldPerm keyword:><input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>">
+              (comma separated)<:or:><: article threshold :><:eif:></td>
             <td bgcolor="#FFFFFF"><:help edit keywords:> </td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left">List article:</th>
-            <td bgcolor="#FFFFFF" width="100%"> <:list listed:> </td>
+            <td bgcolor="#FFFFFF" width="100%"> <:if FieldPerm listed:><:list listed:><:or FieldPerm:><:if Article listed:><:ifEq [article listed] "1":>Yes<:or:>In Sections, but not menu<:eif:><:or Article:>No<:eif Article:><:eif FieldPerm:> </td>
             <td bgcolor="#FFFFFF"><:help edit listed:></td>
           </tr>
           <tr> 
             <th nowrap bgcolor="#FFFFFF" align="left" valign="top">Thumbnail image:</th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type=file name=thumbnail>
+              <:ifFieldPerm thumbImage:><input type=file name=thumbnail><:or:><:eif:>
               <:ifArticle thumbImage:><img src="/images/<:article thumbImage:>"> 
-              <input type=checkbox name="remove_thumb">
-              Remove<:or:><:eif:></td>
+              <:if FieldPerm thumbImage:><input type=checkbox name="remove_thumb">
+              Remove<:or FieldPerm:><:eif FieldPerm:><:or:><:eif:></td>
             <td bgcolor="#FFFFFF" valign="top"><:help edit thumb:></td>
           </tr>
           <:if Article id:> 
             <th nowrap bgcolor="#FFFFFF" align="left" valign="top"><a name="files"></a>Files:</th>
             <td nowrap bgcolor="#FFFFFF" width="100%"> <:if Files:> 
               <table cellpadding="0" cellspacing="0" border="0" bgcolor="#333333">
-                <tr><td> 
+                <tr>
+                  <td> 
                     <table cellpadding="5" cellspacing="1" border="0">
                       <tr bgcolor="#FFFFFF"> 
                         <th>Filename</th>
                       </tr>
                       <:iterator end files:> 
                     </table>
-              </td></tr></table>
+                  </td>
+                </tr>
+              </table>
               <p><a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a>
               </p>
               <:or Files:>
-              <p>No files are attached to this article. <a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a></p><:eif Files:>
+              <p>No files are attached to this article. <a href="<:script:>?filelist=1&id=<:article id:>"><b>Manage Files</b></a></p>
+              <:eif Files:>
             </td>
             <td nowrap bgcolor="#FFFFFF" valign="top"><:help edit files:></td>
           </tr>
               <hr noshade size="1">
               <: iterator end images :>
               <p align="left"><a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
-             <:or Images:><p align="left">No images are attached to this article.  <a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
-             <:eif Images:>
+              <:or Images:>
+              <p align="left">No images are attached to this article.  <a href="<:script:>?id=<:article id:>&showimages=1"><b>Manage Images</b></a></p>
+              <:eif Images:>
            </td>
             <td bgcolor="#FFFFFF" valign="top"><:help edit images:> </td>
           </tr>
 </tr>
 </table>
 
-  <p>
-    <input type="submit" name="save"
-           value="  <: ifnew :>Add New<: or :>Update<: eif :> <: articleType :>  "></p>
+  <p><: ifnew :>
+    <input type="submit" name="save" value="  Add New <: articleType:>  ">
+   <:or:>
+  <:if UserCan edit_save article:><input type="submit" name="save" value="  Update <: articleType:>  "><:or UserCan:><:eif UserCan:>
+   <:eif:></p>
   </form>
 <:if children:> <:ifEq [article id] 3:> 
 <h2>Catalogs</h2>
           <th>Listed</th>
           <th nowrap>Modify</th>
         </tr>
+<:if UserCan edit_reorder_children:>
         <tr> 
           <td colspan="4" bgcolor="#FFFFFF">Reorder child articles: <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=title&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             title</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=date&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             date</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&reverse=1&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">reverse 
             order</a></td>
         </tr>
+<:or UserCan:><:eif UserCan:>
         <:iterator begin children:> 
         <tr bgcolor="#FFFFFF"> 
           <td width="30%"><a href="<:child admin:>"><:child title:></a></td>
           <td width="70%"><: summary child body :></td>
           <td align="center"><: is child listed :></td>
           <td nowrap> <a href="/cgi-bin/admin/add.pl?id=<:child id:>">Edit</a> 
-            <a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>')">Delete</a> 
+            <:if UserCan edit_delete_article child:><a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>')">Delete</a><:or UserCan:><:eif UserCan:>
             <:movechild:> </td>
         </tr>
         <:iterator separator children:> <:iterator end children:> 
 <:if HaveChildType:>
 <:if new:>
 <:or new:>
-<form action="/cgi-bin/admin/add.pl">
+<:if UserCan edit_add_child article:><form action="/cgi-bin/admin/add.pl">
 <input type=hidden name="parentid" value="<:article id:>">
   <p> 
     <input type=submit value="Add <:ifEq [article id] 3:>Catalog<:or:><: childtype :><:eif:>">
   </p>
-</form>
+</form><:or UserCan:><:eif UserCan:>
 <:eif new:> <:or HaveChildType:> <:eif HaveChildType:>
 <p><font size="-1">BSE Release <:release:></font></p>
 </body></html>
index a079f3f..25d3e4b 100644 (file)
@@ -14,7 +14,7 @@
 <:ifMessage:> 
 <p><b><:message:></b></p>
 <:or:><:eif:> 
-<p>| <a href="/admin/">Admin menu</a> | <:ifnew:><:or:><a href="<:article admin:>">See 
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <:ifnew:><:or:><a href="<:article admin:>">See 
   catalog</a> | <:eif:><:editParent:> <a href="/cgi-bin/admin/shopadmin.pl">Manage 
   catalogs</a> | <:if new:><:or new:><a href="<:script:>?id=<:article id:>&_t=steps">Manage 
   step children/parents</a> | <:eif new:></p>
   <h2>Catalog Details</h2>
 
 <:ifnew:><:or:>
-<table><tr><td nowrap><form action="/cgi-bin/admin/adminusers.pl"><font size=2>Manage access: <input type=hidden name=id value="<: article id:>">
-<select name=adminid>
+<:if Or [iadminuser_count] [iadmingroup_count]:>
+      <form action="/cgi-bin/admin/adminusers.pl">
+  <input type=hidden name=id value="<: article id:>">
+  <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
+  <tr>
+    <td>
+        <table cellpadding="6" cellspacing="1" border="0" width="100%">
+          <tr>
+            <th nowrap>
+
+        <font size=2>Manage access:</font>
+        </th>
+            <td bgcolor="#FFFFFF">
+              <select name=adminid>
 <:iterator begin adminusers:>
 <option value=<:iadminuser id:>>User <:iadminuser logon:>
 <:iterator end adminusers:>
 <:iterator begin admingroups:>
 <option value=<:iadmingroup id:>>Group <:iadmingroup name:>
 <:iterator end admingroups:>
-</select><input type=submit name="a_showobjectart" value="Manage">
-</font></form></td></tr></table><:eif:>
+              </select>
+              <input type=submit name="a_showobjectart" value="Manage">
+      </td>
+            <td bgcolor="#FFFFFF"><:help access manage:>
+        </td>
+          </tr>
+        </table>
+    </td>
+   </tr>
+  </table>
+      </form>
+<br>
+<:or Or:><:eif Or:>
+<:eif:>
 
   <form enctype="multipart/form-data" method="POST" action="<:script:>">
   <input type=hidden name=type value="Catalog">
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Parent: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <select name="parentid">
+              <:if FieldPerm parentid:><select name="parentid">
                 <option value="">Please Select a <: parentType :> <: list subsections 
                 :> 
-              </select>
+              </select><:or FieldPerm:><:parent title:> (<:parent id:>)<:eif FieldPerm:>
             </td>
             <td bgcolor="#FFFFFF"><:help catalog parent:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Catalog title: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="title" maxlength="64" size="64" value="<: article title :>">
+              <:ifFieldPerm title:><input type="text" name="title" maxlength="64" size="64" value="<: article title :>"><:or:><:default title:><:eif:>
             </td>
             <td bgcolor="#FFFFFF"><:help catalog title:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Template: </th>
-            <td bgcolor="#FFFFFF" width="100%"> <:templates:> </td>
+            <td bgcolor="#FFFFFF" width="100%"> <:ifFieldPerm titleImage:><:templates:><:or:><:article titleImage:><:eif:> </td>
             <td bgcolor="#FFFFFF"><:help catalog template:></td>
           </tr>
           <tr> 
             <th valign="top" bgcolor="#FFFFFF" nowrap align="left"> Body:</th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea>
+              <:ifFieldPerm body:><textarea name="body" rows="10" cols="60" wrap="virtual"><: article body :></textarea><:or:><:bodytext article body:><:eif:>
             </td>
             <td bgcolor="#FFFFFF" valign="top"><:help body body:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Release date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
-              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)</td>
+              <:if FieldPerm release:><input type="text" name="release" value="<: date "%d/%m/%Y" article release :>" size="10" maxlength="10">
+              (dd/mm/yyyy<: ifnew :> - default is today<: or :><: eif :>)<:or FieldPerm:><: date "%d/%m/%Y" article release :><:eif FieldPerm:></td></td>
             <td bgcolor="#FFFFFF"><:help catalog release:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Expiry date: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
+              <:if FieldPerm expire:><input type="text" name="expire" value="<: date "%d/%m/%Y" article expire :>" size="10" maxlength="10">
               (dd/mm/yyyy - <: ifnew :>default is never, <: or :><: eif :>blank 
-              for never expires)</td>
+              for never expires)<:or FieldPerm:><: date "%d/%m/%Y" article expire :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help catalog expire:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Summary length: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
+              <:if FieldPerm summaryLength:><input type="text" name="summaryLength" size="10" maxlength="10" value="<: article summaryLength :>">
               (in characters - default inherited from parent catalog or shop, zero 
-              for no summary)</td>
+              for no summary)<:or FieldPerm:><: article summaryLength :><:eif FieldPerm:></td>
             <td bgcolor="#FFFFFF"><:help catalog summary:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Display threshold: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>">
+              <:ifFieldPerm threshold:><input type="text" name="threshold" size="10" maxlength="10" value="<: article threshold :>"><:or:><: article threshold :><:eif:>
             </td>
             <td bgcolor="#FFFFFF"><:help catalog threshold:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left"> Keywords: </th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>">
+              <:ifFieldPerm keyword:><input type="text" name="keyword" maxlength="255" size="60" value="<: article keyword :>"><:or:><: article threshold :><:eif:>
               (comma separated) </td>
             <td bgcolor="#FFFFFF"><:help catalog keywords:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left">List article:</th>
-            <td bgcolor="#FFFFFF" width="100%"> <:list listed:> </td>
+            <td bgcolor="#FFFFFF" width="100%"> <:if FieldPerm listed:><:list listed:><:or FieldPerm:><:if Article listed:><:ifEq [article listed] "1":>Yes<:or:>In Sections, but not menu<:eif:><:or Article:>No<:eif Article:><:eif FieldPerm:> </td>
             <td bgcolor="#FFFFFF"><:help catalog list:></td>
           </tr>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left" valign="top">Thumbnail image:</th>
             <td bgcolor="#FFFFFF" width="100%"> 
-              <input type=file name=thumbnail>
+              <:ifFieldPerm thumbImage:><input type=file name=thumbnail><:or:><:eif:>
               <:ifArticle thumbImage:><img src="/images/<:article thumbImage:>"> 
-              <input type=checkbox name="remove_thumb">
-              Remove<:or:><:eif:></td>
+              <:if FieldPerm thumbImage:><input type=checkbox name="remove_thumb">
+              Remove<:or FieldPerm:><:eif FieldPerm:><:or:><:eif:></td>
             <td bgcolor="#FFFFFF" valign="top"><:help catalog thumb:></td>
           </tr>
           <:if Article id:> 
 </tr>
 </table>
 
-  <p>
+  <p><: ifnew :>
     <input type="submit" name="save"
-           value="  <: ifnew :>Add New<: or :>Update<: eif :> Catalog  "></p>
+           value="  Add New Catalog  ">
+     <: or :>
+    <:if UserCan edit_save article:><input type="submit" name="save"
+           value="  Update Catalog  "><:or UserCan:><:eif UserCan:><:eif:></p>
   </form>
 <:if children:>
 <h2>Products / Sub-catalogs</h2>
           <th>Listed</th>
           <th nowrap>Modify</th>
         </tr>
+<:if UserCan edit_reorder_children:>
         <tr> 
           <td colspan="4" bgcolor="#FFFFFF">Reorder child articles: <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=title&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             title</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&sort=date&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">by 
             date</a> | <a href="/cgi-bin/admin/reorder.pl?parentid=<:article id:>&reverse=1&refreshto=/cgi-bin/admin/add.pl?id=<:article id:>">reverse 
             order</a></td>
         </tr>
+<:or UserCan:><:eif UserCan:>
         <:iterator begin children:> 
         <tr bgcolor="#FFFFFF"> 
           <td width="30%"><a href="<:child admin:>"><:child title:></a></td>
           <td width="70%"><: summary child body :></td>
           <td align="center"><: is child listed :></td>
-          <td nowrap> <: edit child Edit :> <a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifMatch [child generator] "Product":>Product<:or:>Sub-catalog<:eif:>')">Delete</a><:movechild:> </td>
+          <td nowrap> <: edit child Edit :> <:if UserCan edit_delete_article child:><a href="/cgi-bin/admin/add.pl?id=<:child id:>&remove=1" onClick="return window.confirm('Are you sure you want to delete this <:ifMatch [child generator] "Product":>Product<:or:>Sub-catalog<:eif:>')">Delete</a><:or UserCan:><:eif UserCan:>
+         <:movechild:> </td>
         </tr>
         <:iterator separator children:> <:iterator end children:> 
       </table>
 <:if HaveChildType:>
 <:if new:>
 <:or new:>
+<:if UserCan edit_add_child article:>
 <p>
 <form action="/cgi-bin/admin/add.pl" method="POST">
 <input type=hidden name="parentid" value="<:article id:>">
 <input type=hidden name="parentid" value="<:article id:>">
 <input type=hidden name="parentid" value="Product">
     <input type=submit value="Add Product">
-</form></p>
+</form><:or UserCan:><:eif UserCan:></p>
 <:eif new:> <:or HaveChildType:> <:eif HaveChildType:> 
 <p><font size="-1">BSE Release <:release:></font></p>
 </body
index 320885e..0f70f7d 100644 (file)
@@ -6,7 +6,7 @@
 <:ifMessage:>
 <p><b><:message:></b></p>
 <:or:><:eif:> 
-<p>| <a href="/admin/">Admin menu</a> | <a href="<:product admin:>">See product</a> 
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <a href="<:product admin:>">See product</a> 
   | <a href="/cgi-bin/admin/add.pl?id=<:product parentid:>">Edit parent</a> 
   | <a href="/cgi-bin/admin/shopadmin.pl">Manage catalogs</a><:if Product listed:> 
   | <a href="<:script:>?id=<:product id:>&delete_product=1">Hide product</a> <:or 
   <:eif Product:>| <a href="/cgi-bin/admin/add.pl?id=<:product id:>&_t=steps">Manage 
   step parents</a> | <:ifProduct listed:><:or:>Hidden<:eif:></p>
   <h2>Edit Product</h2>
-<table><tr><td nowrap><form action="/cgi-bin/admin/adminusers.pl"><font size=2>Manage access: <input type=hidden name=id value="<: article id:>">
-<select name=adminid>
+<:if Or [iadminuser_count] [iadmingroup_count]:>
+      <form action="/cgi-bin/admin/adminusers.pl">
+  <input type=hidden name=id value="<: article id:>">
+  <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
+  <tr>
+    <td>
+        <table cellpadding="6" cellspacing="1" border="0" width="100%">
+          <tr>
+            <th nowrap>
+
+        <font size=2>Manage access:</font>
+        </th>
+            <td bgcolor="#FFFFFF">
+              <select name=adminid>
 <:iterator begin adminusers:>
 <option value=<:iadminuser id:>>User <:iadminuser logon:>
 <:iterator end adminusers:>
 <:iterator begin admingroups:>
 <option value=<:iadmingroup id:>>Group <:iadmingroup name:>
 <:iterator end admingroups:>
-</select><input type=submit name="a_showobjectart" value="Manage">
-</font></form></td></tr></table>
+              </select>
+              <input type=submit name="a_showobjectart" value="Manage">
+      </td>
+            <td bgcolor="#FFFFFF"><:help access manage:>
+        </td>
+          </tr>
+        </table>
+    </td>
+   </tr>
+  </table>
+      </form>
+<br>
+<:or Or:><:eif Or:>
 <form action="<:script:>" enctype="multipart/form-data" method="POST">
     <input type="hidden" name="id" value="<:product id:>">
   <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
         <table border=0 cellpadding="6" cellspacing="1" width="100%">
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Title:</th>
-            <td bgcolor="#FFFFFF"><:product title:></td>
+            <td bgcolor="#FFFFFF"><:ifFieldPerm title:><input type="text" name="title" value="<:old title:>" size="60"><:or:><:product title:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product title:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF">Summary:</th>
-            <td nowrap bgcolor="#FFFFFF"><:product summary:></td>
+            <td nowrap bgcolor="#FFFFFF"><:ifFieldPerm summary:><input type="text" name="summary" value="<:old summary:>" size=60><:or:><:product summary:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product summary:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Catalog:</th>
             <td bgcolor="#FFFFFF">
-<select name="parentid"><:list:></select></td>
+<:ifFieldPerm parentid:><select name="parentid"><:list:></select><:or:><:parent title:> (<:parent id:>)<:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product catalog:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF">Template:</th>
-            <td nowrap bgcolor="#FFFFFF"><:templates:></td>
+            <td nowrap bgcolor="#FFFFFF"><:ifFieldPerm template:><:templates:><:or:><:product template:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product template:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF" valign="top"> Body:</th>
             <td bgcolor="#FFFFFF"> 
-              <textarea name=body rows=15 cols=60 wrap=virtual><:product body:></textarea>
+              <:ifFieldPerm body:><textarea name=body rows=15 cols=60 wrap=virtual><:product body:></textarea><:or:><:bodytext product body:><:eif:>
             </td>
             <td nowrap bgcolor="#FFFFFF" valign="top"><:help body body:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF">Lead time:</th>
             <td nowrap bgcolor="#FFFFFF"> 
-              <input type="text" name="leadTime" value="<:product leadTime:>" size=5>
+              <:ifFieldPerm leadTime:><input type="text" name="leadTime" value="<:product leadTime:>" size=5><:or:><:product leadTime:><:eif:>
               days</td>
             <td nowrap bgcolor="#FFFFFF"><:help product leadtime:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Retail price:</th>
             <td bgcolor="#FFFFFF">$ 
-              <input type="text" name="retailPrice" value="<:money product retailPrice:>" size=7>
-              (0.00)</td>
+              <:ifFieldPerm retailPrice:><input type="text" name="retailPrice" value="<:money product retailPrice:>" size=7>
+              (0.00)<:or:><:money product retailPrice:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product retail:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Wholesale price:</th>
             <td bgcolor="#FFFFFF">$ 
-              <input type="text" name="wholesalePrice" value="<:money product wholesalePrice:>" size=7>
-              (0.00)</td>
+              <:ifFieldPerm wholesalePrice:><input type="text" name="wholesalePrice" value="<:money product wholesalePrice:>" size=7>
+              (0.00)<:or:><:money product wholesalePrice:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product wholesale:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">GST:</th>
             <td bgcolor="#FFFFFF">$ 
-              <input type="text" name="gst" value="<:money product gst:>" size=7>
-              (0.00)</td>
+              <:ifFieldPerm gst:><input type="text" name="gst" value="<:money product gst:>" size=7>
+              (0.00)<:or:><:money product gst:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product gst:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Release date:</th>
             <td bgcolor="#FFFFFF"> 
-              <input type="text" name="release" value="<:date "%d/%m/%Y" product release:>" size=11>
-              (dd/mm/yyyy)</td>
+              <:ifFieldPerm release:><input type="text" name="release" value="<:date "%d/%m/%Y" product release:>" size=11>
+              (dd/mm/yyyy)<:or:><:date "%d/%m/%Y" product release:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product release:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Expiry date:</th>
             <td bgcolor="#FFFFFF"> 
-              <input type="text" name="expire" value="<:date "%d/%m/%Y" product expire:>" size=11>
-              (dd/mm/yyyy)</td>
+              <:ifFieldPerm expire:><input type="text" name="expire" value="<:date "%d/%m/%Y" product expire:>" size=11>
+              (dd/mm/yyyy)<:or:><:date "%d/%m/%Y" product expire:><:eif:></td>
             <td nowrap bgcolor="#FFFFFF"><:help product expire:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF">Summary length:</th>
             <td nowrap bgcolor="#FFFFFF"> 
-              <input type="text" name="summaryLength" size="10" maxlength="10" value="<:product summaryLength:>">
+              <:ifFieldPerm summaryLength:><input type="text" name="summaryLength" size="10" maxlength="10" value="<:product summaryLength:>"><:or:><:product summaryLength:><:eif:>
             </td>
             <td nowrap bgcolor="#FFFFFF"><:help product summary:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF">Display threshold:</th>
             <td nowrap bgcolor="#FFFFFF"> 
-              <input type="text" name="threshold" size=10 maxlength=10 value="<:product threshold:>">
+              <:ifFieldPerm threshold:><input type="text" name="threshold" size=10 maxlength=10 value="<:product threshold:>"><:or:><:product threshold:><:eif:>
             </td>
             <td nowrap bgcolor="#FFFFFF"><:help product threshold:></td>
           </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Options:</th>
             <td bgcolor="#FFFFFF"> 
-              <input type="text" name="options" value="<:product options:>" size=30>
-              (<:alloptions:>) </td>
+              <:ifFieldPerm options:><input type="text" name="options" value="<:product options:>" size=30>
+              (<:alloptions:>)<:or:><:product options:><:eif:> </td>
             <td bgcolor="#FFFFFF"><:help product options:></td>
           </tr>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF" valign="top">Thumbnail image:</th>
             <td nowrap bgcolor="#FFFFFF"> 
-              <input type="file" name="thumbnail">
+              <:ifFieldPerm thumbImage:><input type="file" name="thumbnail"><:or:><:eif:>
               <:ifProduct thumbImage:><img src="/images/<:product thumbImage:>"> 
-              <input type=checkbox name="remove_thumb">
-              Remove<:or:><:eif:> </td>
+              <:if FieldPerm thumbImage:><input type=checkbox name="remove_thumb">
+              Remove<:or FieldPerm:><:eif FieldPerm:><:or:><:eif:> </td>
             <td nowrap bgcolor="#FFFFFF" valign="top"><:help product thumb:></td>
           </tr>
           <tr> 
       </td>
     </tr>
   </table>
-  <p>
+  <:if UserCan edit_save article:><p>
     <input type=submit name="save" value="Save changes">
-  </p>
+  </p><:or UserCan:><:eif UserCan:>
 </form>
 
 <p><font size="-1">BSE Release <:release:></font></p>
index ff55416..233bff6 100644 (file)
@@ -13,6 +13,7 @@
 <:ifMessage:>
 <p><b><:message:></b></p>
 <:or:><:eif:> 
+<:if UserCan edit_files_add article:>
 <h2>Add new file</h2>
 
 <form method="post" action="<:script:>" enctype="multipart/form-data">
@@ -75,6 +76,7 @@
   </table>
 </form>
 
+<:or UserCan:><:eif UserCan:>
   
 <h2>Manage files</h2>
 
           <tr bgcolor="#FFFFFF"> 
             <td nowrap> <:file displayName:></td>
             <td valign="top"> 
-              <input type="text" name="description_<:file id:>" value="<: file description :>" />
+              <:ifUserCan edit_files_save article:><input type="text" name="description_<:file id:>" value="<: file description :>" /><:or:><: file description :><:eif:>
             </td>
             <td valign="top"> 
-              <input type="text" name="contentType_<:file id:>" value="<: file contentType :>" />
+               <:ifUserCan edit_files_save article:><input type="text" name="contentType_<:file id:>" value="<: file contentType :>" /><:or:><: file contentType :><:eif:>
             </td>
           </tr>
           <tr bgcolor="#FFFFFF"> 
             <td colspan="3"> 
               <table width="100%" border="0" cellspacing="0" cellpadding="0">
                 <tr bgcolor="#FFFFFF"> 
-                  <td valign="top" align="center" nowrap> <input type="checkbox" name="download_<:file id:>"
-                    <:ifFile download:> checked<:or:><:eif:> />Download&nbsp;&nbsp;&nbsp;</td>
-                  <td valign="top" align="center" nowrap> <input type="checkbox" name="forSale_<:file id:>"
-                    <:ifFile forSale:> checked<:or:><:eif:> />Require payment&nbsp;&nbsp;&nbsp;</td>
-                  <td valign="top" align="center" nowrap> <input type="checkbox" name="requireUser_<:file id:>"
-                    <:ifFile requireUser:> checked<:or:><:eif:> />Require login 
+                  <td valign="top" align="center" nowrap> <:if UserCan edit_files_save article:><input type="checkbox" name="download_<:file id:>"
+                    <:ifFile download:> checked<:or:><:eif:> /><:or UserCan:><img src="/images/admin/<:ifFile download:>checked.gif<:or:>unchecked.gif<:eif:>" width="16" height="16" /><:eif UserCan:>Download&nbsp;&nbsp;&nbsp;</td>
+                  <td valign="top" align="center" nowrap> <:if UserCan edit_files_save article:><input type="checkbox" name="forSale_<:file id:>"
+                    <:ifFile forSale:> checked<:or:><:eif:> /><:or UserCan:><img src="/images/admin/<:ifFile forSale:>checked.gif<:or:>unchecked.gif<:eif:>" width="16" height="16" /><:eif UserCan:>Require payment&nbsp;&nbsp;&nbsp;</td>
+                  <td valign="top" align="center" nowrap> <:if UserCan edit_files_save article:><input type="checkbox" name="requireUser_<:file id:>"
+                    <:ifFile requireUser:> checked<:or:><:eif:> /><:or UserCan:><img src="/images/admin/<:ifFile requireUser:>checked.gif<:or:>unchecked.gif<:eif:>" width="16" height="16" /><:eif UserCan:>Require login 
                     &nbsp;&nbsp;&nbsp;</td>
-                  <td nowrap align="right" width="100%"> <b><a href="<:script:>?filedel=1&amp;id=<:article id:>&amp;file=<:file id:>" onClick="return window.confirm('Are you sure you want to delete this File')">Delete</a></b> 
+                  <td nowrap align="right" width="100%"> <:ifUserCan edit_files_delete article:><b><a href="<:script:>?filedel=1&amp;id=<:article id:>&amp;file=<:file id:>" onClick="return window.confirm('Are you sure you want to delete this File')">Delete</a></b> <:or:><:eif:>
                     <:movefiles:></td>
                 </tr>
               </table>
             <td colspan="3">&nbsp;</td>
           </tr>
           <: iterator end files :> 
+<:ifUserCan edit_files_save article:>
           <tr> 
             <td colspan="3" align="right" valign="bottom" bgcolor="#FFFFFF"> 
               <input type="submit" name="filesave" value="  Save changes  " />
             </td>
           </tr>
+<:or:><:eif:>
           <:or Files:> 
           <tr bgcolor="#FFFFFF"> 
             <td colspan="3" align="center">No files are attached to this article</td>
index b5011de..8a40b53 100644 (file)
@@ -67,7 +67,7 @@ article</a></td>
     <td colspan="2"><a 
 href="/cgi-bin/admin/shopadmin.pl">Shop administration</a></td>
  
-<:if UserCan shop_show_orders :>
+<:if UserCan shop_order_list :>
 </tr>
   <tr> 
     <td 
index 89850ec..56c2c59 100644 (file)
@@ -6,9 +6,9 @@
 <h1>Shop Administration</h1>
 <:ifMessage:><p><b><:message:></b></p>
 <:or:><:eif:> 
-<p>| <a href="/admin/">Admin menu</a> | <a href="/cgi-bin/admin/admin.pl?id=<:shopid:>">See 
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <a href="/cgi-bin/admin/admin.pl?id=<:shopid:>">See 
   shop</a> | <a href="/cgi-bin/admin/add.pl?id=<:shopid:>">Edit shop</a> 
-  | <a href="<:script:>?order_list=1">Manage orders</a> | <a href="/cgi-bin/admin/admin.pl?id=<:shopid:>"></a><:if 
+  | <:ifUserCan shop_order_list:><a href="<:script:>?order_list=1">Manage orders</a> | <:or:><:eif:><a href="/cgi-bin/admin/admin.pl?id=<:shopid:>"></a><:if 
   ShowStepKids:><a href="<:script:>?showstepkids=0">Hide step children</a><:or 
   ShowStepKids:><a href="<:script:>?showstepkids=1">Show step children</a><:eif 
   ShowStepKids:> | </p>
@@ -18,8 +18,8 @@
 <p>&nbsp; </p>
 <hr noshade size="1">
 <:iterator end catalogs:> 
-<form action="/cgi-bin/admin/add.pl"><input type=hidden name=type value="Catalog">
-  <input type=hidden name=parentid value=3><input type=submit value="Add Catalog"></form>
+<:ifUserCan edit_add_child [cfg articles shop]:><form action="/cgi-bin/admin/add.pl"><input type=hidden name=type value="Catalog">
+  <input type=hidden name=parentid value=3><input type=submit value="Add Catalog"></form><:or:><:eif:>
 <p><font size="-1">BSE Release <:release:></font></p>
 </body>
 </html>
\ No newline at end of file
index 6f585f3..93a1b09 100644 (file)
@@ -14,8 +14,8 @@
 
 <:ifMessage:><p><b><:message:></b></p><:or:><:eif:>
 
-<p>| <a href="/admin/">Admin menu</a> | <a href="<:script:>?add=1">Add New Subscription</a> 
-  |</p>
+<p>| <a href="/admin/">Admin menu</a> | <:ifUserCan subs_add:><a href="<:script:>?add=1">Add New Subscription</a> 
+  |<:or:><:eif:></p>
 
 <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" class="table">
     <tr>
@@ -37,8 +37,8 @@
       <td><:subscription frequency:></td>
       <td align="center"><:ifSubscription visible:>Yes<:or:>No<:eif:></td>
       <td align="center"><:ifMatch [subscription lastSent] "0000-00-00":>Never<:or:><:date subscription lastSent:><:eif:></td>
-          <td nowrap> <a href="<:script:>?edit=1&id=<:subscription id:>"><b>Edit</b></a> 
-            <a href="<:script:>?start_send=1&id=<:subscription id:>"><b>Send</b></a> 
+          <td nowrap> <:ifUserCan subs_edit:><a href="<:script:>?edit=1&id=<:subscription id:>"><b>Edit</b></a> <:or:><:eif:>
+            <:ifUserCan subs_edit:><a href="<:script:>?start_send=1&id=<:subscription id:>"><b>Send</b></a>  <:or:><:eif:>
           </td>
     </tr>
 <:iterator end subscriptions:>
index aa4f97c..0d4839e 100644 (file)
                 <td><img src="/images/trans_pixel.gif" width="1" height="1" alt="spacer"></td>
               </tr>
             </table>
-            <:iterator begin level1:> <:if Level2:> 
+            <:iterator begin level1:>  
             <table width="100%" border="0" cellspacing="0" cellpadding="0">
               <tr> 
                 <td> 
                   <table width="100%" border="0" cellspacing="0" cellpadding="0">
-                    <tr bgcolor="#CCCCFF"> 
+                    <:if Ancestor level1:>
+                    <tr> 
+                      <td height="19" width="100%" nowrap bgcolor="#999999">&nbsp;<a href="<:url level1:>"><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"><:level1 
+                        title:></font></b></a> </td>
+                    </tr>
+                    <:or Ancestor:>
+                    <tr> 
                       <td height="19" width="100%" nowrap bgcolor="#CCCCCC">&nbsp;<a href="<:url level1:>"><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:level1 
                         title:></font></b></a> </td>
                     </tr>
+                    <:eif Ancestor:>
                   </table>
                 </td>
               </tr>
-              <tr> 
-                <td> 
-                  <table width="100%" border="0" cellspacing="0" cellpadding="5">
-                    <tr> 
-                      <td bgcolor="#EEEEEE"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:iterator 
-                        begin level2:><a href="<:url level2:>"><:level2 title:></a> 
-                        <:iterator separator level2:><br>
-                        <img src="/images/trans_pixel.gif" width="2" height="4" border="0"><br>
-                        <:iterator end level2:> </font></td>
-                    </tr>
+              <:if Ancestor level1:>
+               <tr> 
+                <td>
+                 <:if Level2:> 
+                  <table width="100%" border="0" cellspacing="0" cellpadding="3">
+                    <:iterator begin level2:>
+                    <:ifAncestor level2:>
+                     <tr> 
+                      <td bgcolor="#FFFFFF"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><a href="<:url level2:>"><:level2 title:></a></font> 
+                        </td>
+                     </tr>
+                     <:or:>
+                     <tr> 
+                      <td bgcolor="#EEEEEE"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><a href="<:url level2:>"><:level2 title:></a></font> 
+                        </td>
+                     </tr>
+                     <:eif:>
+                        <:iterator end level2:>
                   </table>
+            <:or Level2:> 
+            <:eif Level2:>
                 </td>
               </tr>
+<:or Ancestor:>
+<:eif Ancestor:>
               <tr> 
                 <td><img src="/images/trans_pixel.gif" width="1" height="1" alt="spacer"></td>
               </tr>
             </table>
-            <:or Level2:> 
-            <table width="100%" border="0" cellspacing="0" cellpadding="0">
-              <tr> 
-                <td> 
-                  <table width="100%" border="0" cellspacing="0" cellpadding="0">
-                    <tr bgcolor="#CCCCFF"> 
-                      <td height="20" width="100%" nowrap bgcolor="#CCCCCC">&nbsp;<a href="<:url level1:>"><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:level1 
-                        title:></font></b></a></td>
-                    </tr>
-                    <tr> 
-                      <td><img src="/images/trans_pixel.gif" width="1" height="1" alt="spacer"></td>
-                    </tr>
-                  </table>
-                </td>
-              </tr>
-            </table>
-            <:eif Level2:><:iterator separator level1:><:iterator end level1:> 
+<:iterator separator level1:><:iterator end level1:> 
             <:embed 5:> </td>
         </tr>
       </table>
index d967a2a..4b13dc8 100644 (file)
@@ -23,7 +23,7 @@
 </table>
 <:ifMsg:><p><font face="Verdana, Arial, Helvetica, sans-serif"><b><:msg:></b> </font></p><:or:><:eif:>
 <p><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>Contains</b> 
-  - <:count:> items</font></p>
+  - <:count:> item<:if Eq [count] "1":><:or Eq:>s<:eif Eq:></font></p>
 <form name="form1" method="POST" action="/cgi-bin/shop.pl">
   <table width="100%" border="0" cellspacing="0" cellpadding="0">
     <tr> 
@@ -34,7 +34,7 @@
   <table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#666666">
     <tr valign="middle" align="center"> 
       <td width="100%"> 
-        <table width="100%" border="0" cellspacing="0" cellpadding="2">
+        <table width="100%" border="0" cellspacing="1" cellpadding="1" bgcolor="#EEEEEE">
           <tr valign="middle" align="center" bgcolor="#666666"> 
             <td width="100%" align="left" height="18"> &nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF"><b>Item:</b></font>&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF">(All 
               prices in AUD &#150; includes GST and shipping costs where applicable)</font></td>
index 59b19dd..bfdd3e6 100644 (file)
@@ -76,7 +76,7 @@ function BSE_validateForm {
 <table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#666666">
   <tr valign="middle" align="center"> 
     <td width="100%"> 
-      <table width="100%" border="0" cellspacing="0" cellpadding="2">
+      <table width="100%" border="0" cellspacing="1" cellpadding="2" bgcolor="#EEEEEE">
         <tr valign="middle" align="center" bgcolor="#666666"> 
           <td width="100%" align="left" height="18"> &nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF"><b>Item:</b></font>&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF">(All 
             prices in AUD &#150; includes GST and shipping costs where applicable)</font></td>
@@ -85,8 +85,8 @@ function BSE_validateForm {
         </tr>
         <:iterator begin items:> 
         <tr valign="middle" align="center" bgcolor="#FFFFFF"> 
-          <td width="100%" align="left"> &nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:item 
-            summary:>  <:options:></font></td>
+          <td width="100%" align="left"> &nbsp;<a href="<:item link:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:item 
+            summary:>  <:options:></font></a></td>
           <td nowrap align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:item 
             units:></font></td>
           <td align="right"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>$<: 
@@ -97,7 +97,7 @@ function BSE_validateForm {
     </td>
   </tr>
 </table>
-<table width="100%" border="0" cellspacing="0" cellpadding="0">
+<table width="100%" border="0" cellspacing="0" cellpadding="0">   
   <tr> 
     <td>&nbsp;</td>
     <td height="20">&nbsp;</td>
@@ -107,8 +107,8 @@ function BSE_validateForm {
     <td height="20" bgcolor="#666666">&nbsp;</td>
   </tr>
   <tr> 
-    <td width="100%" valign="MIDDLE"><a href="/shop/index.html"><img src="/images/store/browse_more.gif" width="133" height="21" border="0" alt="Browse More"></a></td>
-    <td NOWRAP> 
+    <td width="50%" valign="MIDDLE"><a href="/shop/index.html"><img src="/images/store/browse_more.gif" width="133" height="21" border="0" alt="Browse More"></a></td>
+    <td NOWRAP width="50%"
       <table border="0" cellspacing="0" cellpadding="0">
         <tr></tr>
       </table>
@@ -119,8 +119,8 @@ function BSE_validateForm {
     <td><img src="/images/store/right_bottom_corner_line.gif" width="26" height="31"></td>
   </tr>
   <tr> 
-    <td width="100%"></td>
-    <td></td>
+    <td width="50%"></td>
+    <td width="50%"></td>
     <td></td>
     <td bgcolor="#666666"><img src="/images/trans_pixel.gif" width="1" height="1"></td>
     <td></td>
@@ -269,15 +269,11 @@ function BSE_validateForm {
     <tr> 
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">We will 
         include a tax invoice / receipt with your order, clearly showing the GST 
-        and delivery components of the purchase price. These are included in the 
-        price below and are indicated on the details page for each store item.</font></td>
+        and delivery components of the purchase price.</font></td>
     </tr>
   </table>
-  <p></p>
-  <font size="3" face="Arial, Helvetica, sans-serif" color="#FFFFFF"></font> 
-  <p> 
+  <p>
     <input type="submit" value="Purchase Now" name="purchase">
     <input type="reset" value="Reset Form" name="reset">
   </p>
-  <p></p>
-</form>
+  </form>
index 9257519..57f89e6 100644 (file)
@@ -38,6 +38,7 @@
 <:if CallMePayment:>
 <p>We will call you to arrange payment.</p>
 <:or CallMePayment:><:eif CallMePayment:>
+
 </font> 
 <table width="100%" border="0" cellspacing="0" cellpadding="0">
   <tr> 
@@ -48,7 +49,7 @@
 <table border="0" cellspacing="0" cellpadding="1" width="100%" bgcolor="#666666">
   <tr valign="middle" align="center"> 
     <td width="100%"> 
-      <table width="100%" border="0" cellspacing="0" cellpadding="2">
+      <table width="100%" border="0" cellspacing="1" cellpadding="2" bgcolor="#EEEEEE">
         <tr valign="middle" align="center" bgcolor="#666666"> 
           <td width="100%" align="left" height="18"> &nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF"><b>Item:</b></font>&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FFFFFF">(All 
             prices in AUD &#150; includes GST and shipping costs where applicable)</font></td>
@@ -57,8 +58,8 @@
         </tr>
         <:iterator begin items:> 
         <tr valign="middle" align="center" bgcolor="#FFFFFF"> 
-          <td width="100%" align="left"> &nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:product 
-            summary:> <:options:></font></td>
+          <td width="100%" align="left"> &nbsp;<a href="<:item link:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:product 
+            summary:> <:options:></font></a></td>
           <td nowrap align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:item 
             units:></font></td>
           <td align="right"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><b>$<: 
@@ -69,7 +70,7 @@
     </td>
   </tr>
 </table>
-<table width="100%" border="0" cellspacing="0" cellpadding="0">
+<table width="100%" border="0" cellspacing="0" cellpadding="0">    
   <tr> 
     <td>&nbsp;</td>
     <td height="20">&nbsp;</td>
index c5911f7..ee656df 100644 (file)
       </th>
     </tr>
     <tr> 
-      <td colspan="2" align="center"> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">Hello 
-        <:user userId:><br>
-        Last logged in: <:date user lastLogon:><br>
-        <br>
-        </font></td>
+      <td colspan="2" align="center"> 
+        <p><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Hello <:ifUser name1:><:user name1:> <:user name2:><:or:><:user 
+          userId:><:eif:></font></b></p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#999999">Last logged in: <:date user previousLogon:><br>
+          Registered since: <:date user whenRegistered:></font><br>
+          <br>
+        </p>
+        </td>
     </tr>
     <:if Message:> 
     <tr> 
index fe7a609..a2f1bb0 100644 (file)
     </tr>
     <tr>
       <td align="center"> 
-        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Hello <:user 
-          userId:><br>
-          Last logged in: <:date user previousLogon:></font><br>
+        <p><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Hello <:ifUser name1:><:user name1:> <:user name2:><:or:><:user 
+          userId:><:eif:></font></b></p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#999999">Last logged in: <:date user previousLogon:><br>
+          Registered since: <:date user whenRegistered:></font><br>
           <br>
         </p>
         </td>
@@ -80,7 +81,7 @@
 <:iterator end items:>
         </table>
 
-          <:if Prodfiles:> 
+          <:if Orderfiles:> 
         <table width="100%" cellpadding="3" cellspacing="1">
           <tr bgcolor="#CCCCCC"> 
             <th colspan="4"><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#666666"><:if 
             <th nowrap width="50%" align="left" colspan="2"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">File</font></th>
             <th><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Size</font></th>
           </tr>
-<:iterator begin items:>
-          <:iterator begin prodfiles:> 
+          <:iterator begin orderfiles:> 
           <tr bgcolor="#FFFFFF"> 
-            <td width="50%"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:prodfile 
+            <td width="50%"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:orderfile 
               description:></font></td>
             <td nowrap width="50%"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:if 
-              FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:prodfile id:>&order=<:order id:>&item=<:item id:>"><:prodfile 
-              displayName:></a><:or FileAvail:><:prodfile displayName:><:eif FileAvail:></font></td>
-            <td><:if FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:prodfile id:>&order=<:order id:>&item=<:item id:>"><img src="/images/filestatus/download.gif" width="15" height="15" alt="Download now" title="Download now" border="0"></a><:or FileAvail:><img src="/images/filestatus/locked.gif" width="15" height="15" alt="Locked" title="Locked"><:eif FileAvail:></td>
+              FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:orderfile id:>&order=<:order id:>&item=<:orderfile item_id:>"><:orderfile 
+              displayName:></a><:or FileAvail:><:orderfile displayName:><:eif FileAvail:></font></td>
+            <td><:if FileAvail:><a href="/cgi-bin/user.pl?download=1&file=<:orderfile id:>&order=<:order id:>&item=<:orderfile item_id:>"><img src="/images/filestatus/download.gif" width="15" height="15" alt="Download now" title="Download now" border="0"></a><:or FileAvail:><img src="/images/filestatus/locked.gif" width="15" height="15" alt="Locked" title="Locked"><:eif FileAvail:></td>
             <td align="right"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:kb 
-              prodfile sizeInBytes:></font></td>
+              orderfile sizeInBytes:></font></td>
           </tr>
-          <:iterator end prodfiles:><:iterator end items:> 
+          <:iterator end orderfiles:>
         </table>
-<:or Prodfiles:><:eif Prodfiles:>  
+        <:or Orderfiles:><:eif Orderfiles:>  
 <:or Items:><:eif Items:>
         </td>
     </tr>