0.15_21 commit r0_15_21
authorTony Cook <tony@develop-help.com>
Mon, 25 Jul 2005 04:46:07 +0000 (04:46 +0000)
committertony <tony@45cb6cf1-00bc-42d2-bb5a-07f51df49f94>
Mon, 25 Jul 2005 04:46:07 +0000 (04:46 +0000)
25 files changed:
MANIFEST
Makefile
schema/bse.sql
site/cgi-bin/bse.cfg
site/cgi-bin/image.pl [new file with mode: 0755]
site/cgi-bin/modules/Article.pm
site/cgi-bin/modules/BSE/AdminSiteUsers.pm
site/cgi-bin/modules/BSE/DB/Mysql.pm
site/cgi-bin/modules/BSE/Edit/Article.pm
site/cgi-bin/modules/BSE/TB/SiteUserGroup.pm
site/cgi-bin/modules/BSE/TB/SiteUserGroups.pm
site/cgi-bin/modules/BSE/UI/Image.pm [new file with mode: 0644]
site/cgi-bin/modules/BSE/UI/Page.pm
site/cgi-bin/modules/Generate/Article.pm
site/docs/bse.pod
site/docs/config.pod
site/templates/admin/edit_1.tmpl
site/templates/admin/edit_catalog.tmpl
site/templates/admin/edit_groups.tmpl [new file with mode: 0644]
site/templates/admin/edit_product.tmpl
site/templates/admin/edit_seminar.tmpl
site/templates/error_base.tmpl [new file with mode: 0644]
site/templates/image.tmpl [new file with mode: 0644]
site/templates/noartbase.tmpl [new file with mode: 0644]
test.cfg

index a235f3c9cf33fb5a3173ba7515199543926a9d84..8aef5488ec1dd5a3f7b666ee1b143e0c501e79ab 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -34,6 +34,7 @@ site/cgi-bin/admin/subs.pl
 site/cgi-bin/admin/userlist.pl
 site/cgi-bin/bse.cfg
 site/cgi-bin/fmail.pl
+site/cgi-bin/image.pl
 site/cgi-bin/interest.pl
 site/cgi-bin/modules/AdminUtil.pm
 site/cgi-bin/modules/Apache/Session/DBIreal.pm
@@ -120,6 +121,7 @@ site/cgi-bin/modules/BSE/UI/AdminSeminar.pm
 site/cgi-bin/modules/BSE/UI/Affiliate.pm
 site/cgi-bin/modules/BSE/UI/Dispatch.pm
 site/cgi-bin/modules/BSE/UI/Formmail.pm
+site/cgi-bin/modules/BSE/UI/Image.pm
 site/cgi-bin/modules/BSE/UI/Page.pm
 site/cgi-bin/modules/BSE/UI/Shop.pm
 site/cgi-bin/modules/BSE/UI/SiteuserCommon.pm
@@ -276,6 +278,7 @@ site/templates/admin/edit_1.tmpl
 # site/templates/admin/edit_4.tmpl
 # site/templates/admin/edit_5.tmpl
 site/templates/admin/edit_catalog.tmpl
+site/templates/admin/edit_groups.tmpl
 site/templates/admin/edit_product.tmpl
 site/templates/admin/edit_seminar.tmpl
 site/templates/admin/edit_semsessions.tmpl
@@ -366,13 +369,14 @@ site/templates/common/sidebar_section.tmpl
 site/templates/custom/order_detail_payment.include
 # site/templates/custom/payment_type.include
 site/templates/custom/payment_type_email.include
-site/templates/error.tmpl
+site/templates/error_base.tmpl
 site/templates/extras.txt
 site/templates/formmail/defdone_base.tmpl
 site/templates/formmail/defemail.tmpl
 site/templates/formmail/defquery_base.tmpl
 site/templates/helpicon.tmpl   Help icon for user templates
 site/templates/htmlemail/basic.tmpl
+site/templates/image.tmpl
 site/templates/include/rssitems.tmpl
 site/templates/include/rsslinks.tmpl
 site/templates/index.tmpl
@@ -390,6 +394,7 @@ site/templates/menu/menu2.tmpl
 site/templates/menu/menu3.tmpl
 site/templates/menu/menu4.tmpl
 site/templates/menu/menu5.tmpl
+site/templates/noartbase.tmpl
 site/templates/printable/printable.tmpl
 site/templates/printable/wap.tmpl
 site/templates/search_base.tmpl
index 54b65b9f03091658f62f4f90ca438f94ae3f213d..07394ce06896fea30e29ca9cec50149d540edbba 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION=0.15_20
+VERSION=0.15_21
 DISTNAME=bse-$(VERSION)
 DISTBUILD=$(DISTNAME)
 DISTTAR=../$(DISTNAME).tar
index 4f2336c9ef856de8e964d1cf9d077ee14364903b..cb832134c1aed27699238fd1b1308f987747a43a 100644 (file)
@@ -758,3 +758,17 @@ create table bse_siteuser_membership (
   primary key(group_id, siteuser_id),
   index(siteuser_id)
 );
+
+drop table if exists bse_article_groups;
+create table bse_article_groups (
+  article_id integer not null,
+  group_id integer not null,
+  primary key (article_id, group_id)
+);
+
+drop table if exists sql_statements;
+create table sql_statements (
+  name varchar(80) not null primary key,
+  sql_statement text not null
+);
+
index eca91655cc795ecf0a4200a46bbf2fa44e4a188c..eb0d6ec64058446937e42392e0229c6db5381f42 100644 (file)
@@ -45,6 +45,7 @@ interest/askagain.tmpl = interest,interest/askagain_base.tmpl
 interest/error.tmpl = interest,interest/error_base.tmpl
 formmail/defquery.tmpl = formmail,formmail/defquery_base.tmpl
 formmail/defdone.tmpl = formmail,formmail/defdone_base.tmpl
+error.tmpl = error,error_base.tmpl
 
 [user settings]
 title = My $(site/name)
@@ -55,6 +56,9 @@ title = $(site/name) Interest Registration
 [formmail settings]
 title = Send us a comment
 
+[error settings]
+title = Error
+
 [messages]
 user/notyourorder = Order $1 isn't your order
 shop/fileitems = You have products in your cart that include downloadable files.  Please logon or register before checking out.
diff --git a/site/cgi-bin/image.pl b/site/cgi-bin/image.pl
new file mode 100755 (executable)
index 0000000..2cee2b2
--- /dev/null
@@ -0,0 +1,19 @@
+#!/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::DB;
+use BSE::Request;
+use BSE::Template;
+use Carp 'confess';
+use BSE::UI::Image;
+
+$SIG{__DIE__} = sub { confess $@ };
+
+my $req = BSE::Request->new;
+
+my $result = BSE::UI::Image->dispatch($req);
+
+BSE::Template->output_result($req, $result);
index cc057ad63786b4369c54ca845be4cc69a75dbb18..976c72085fb7a49effd5c4635affd23e123c74ce 100644 (file)
@@ -138,7 +138,13 @@ sub update_dynamic {
   $dynamic or $dynamic = $self->{force_dynamic};
 
   unless ($dynamic) {
-    # check for groups, etc
+    my @groups = $self->group_ids;
+    @groups and $dynamic = 1;
+  }
+
+  unless ($dynamic) {
+    my $parent = $self->parent;
+    $parent and $dynamic = $parent->is_dynamic;
   }
 
   $self->{cached_dynamic} = $dynamic;
@@ -148,4 +154,34 @@ sub is_dynamic {
   $_[0]{cached_dynamic};
 }
 
+sub is_accessible_to {
+  my ($self, $group) = @_;
+
+  my $groupid = ref $group ? $group->{id} : $group;
+
+  my @rows = BSE::DB->query(articleAccessibleToGroup => $self->{id}, $groupid);
+
+  scalar @rows;
+}
+
+sub group_ids {
+  my ($self) = @_;
+
+  map $_->{id}, BSE::DB->query(siteuserGroupsForArticle => $self->{id});
+}
+
+sub add_group_id {
+  my ($self, $id) = @_;
+
+  eval {
+    BSE::DB->single->run(articleAddSiteUserGroup => $self->{id}, $id);
+  };
+}
+
+sub remove_group_id {
+  my ($self, $id) = @_;
+
+  BSE::DB->single->run(articleDeleteSiteUserGroup => $self->{id}, $id);
+}
+
 1;
index 88c599ae164a27968a4d1feca5930e4f251e5f2a..70b0c2f2a42392085eda45ed2e04929f0f7a56e7 100644 (file)
@@ -778,11 +778,15 @@ sub req_addgroup {
                 section=>SITEUSER_GROUP_SECT)
     or return $class->req_addgroupform($req, \%errors);
 
-  my $name = $req->cgi->param('name');
+  my $cgi = $req->cgi;
+  my $name = $cgi->param('name');
   my $group = BSE::TB::SiteUserGroups->add($name);
 
-  return BSE::Template->get_refresh("$ENV{SCRIPT_NAME}?a_grouplist=1&m=Group+added", 
-                                   $req->cfg);  
+  my $r = $cgi->param('r');
+  unless ($r) {
+    $r = $req->url('siteusers', { a_grouplist => 1, m => "Group created" });
+  }
+  return BSE::Template->get_refresh($r, $req->cfg);
 }
 
 sub req_editgroup {
@@ -807,11 +811,16 @@ sub req_savegroup {
                 rules=>\%rules,
                 section=>SITEUSER_GROUP_SECT)
     or return $class->req_editgroup($req, \%errors);
-  
-  $group->{name} = $req->cgi->param('name');
+
+  my $cgi = $req->cgi;
+  $group->{name} = $cgi->param('name');
   $group->save;
 
-  return BSE::Template->get_refresh("$ENV{SCRIPT_NAME}?a_grouplist=1&m=Group+saved", $req->cfg);
+  my $r = $cgi->param('r');
+  unless ($r) {
+    $r = $req->url('siteusers', { a_grouplist => 1, m => "Group saved" });
+  }
+  return BSE::Template->get_refresh($r, $req->cfg);
 }
 
 sub _common_group {
@@ -853,7 +862,11 @@ sub req_deletegroup {
 
   $group->remove;
 
-  return BSE::Template->get_refresh("$ENV{SCRIPT_NAME}?a_grouplist=1&m=Group+deleted", $req->cfg);
+  my $r = $req->cgi->param('r');
+  unless ($r) {
+    $r = $req->url('siteusers', { a_grouplist => 1, m => "Group deleted" });
+  }
+  return BSE::Template->get_refresh($r, $req->cfg);
 }
 
 sub tag_ifMember {
@@ -920,7 +933,11 @@ sub req_savegroupmembers {
     }
   }
 
-  return BSE::Template->get_refresh("$ENV{SCRIPT_NAME}?a_grouplist=1&m=Membership+saved", $req->cfg);
+  my $r = $cgi->param('r');
+  unless ($r) {
+    $r = $req->url('siteusers', { a_grouplist => 1, m => "Membership saved" });
+  }
+  return BSE::Template->get_refresh($r, $req->cfg);
 }
 
 1;
index 55efbe7edb247be2f6f007bdced9d8b0f47413ef..7209441acb620351b415637a06ff16cd993b0d9e 100644 (file)
@@ -52,6 +52,10 @@ EOS
    addImage => 'insert image values(null, ?, ?, ?, ?, ?, ?, ?, ?)',
    deleteImage => 'delete from image where id = ?',
    getImageByArticleId => 'select * from image where articleId = ? order by displayOrder',
+   getImageByPkey => 'select * from image where id = ?',
+   getImageByArticleIdAndName => <<SQL,
+select * from image where articleId = ? and name = ?
+SQL
    
    dropIndex => 'delete from searchindex',
    insertIndex => 'insert searchindex values(?, ?, ?, ?)',
@@ -479,6 +483,25 @@ where siteuser_id = ? and group_id = ?
 SQL
     siteuserGroupsForUser => <<SQL,
 select group_id as "id" from bse_siteuser_membership where siteuser_id = ?
+SQL
+
+    articleAccessibleToGroup => <<SQL,
+select * from bse_article_groups
+where article_id = ? and group_id = ?
+SQL
+    siteuserGroupsForArticle => <<SQL,
+select group_id as "id" from bse_article_groups
+where article_id = ?
+SQL
+    articleAddSiteUserGroup => <<SQL,
+insert bse_article_groups values(?,?)
+SQL
+    articleDeleteSiteUserGroup => <<SQL,
+delete from bse_article_groups 
+where article_id = ? and group_id = ?
+SQL
+    siteuserGroupDeleteAllPermissions => <<SQL,
+delete from bse_article_groups where group_id = ?
 SQL
   );
 
index 25ee600d650c47beedbefea4daf8505295a859fe..4fdcc10df1e0d056a3fbecec8c78a54017ffa0eb 100644 (file)
@@ -1047,6 +1047,8 @@ sub low_edit_tags {
   my @stepparentpossibles;
   my @files;
   my $file_index;
+  my @groups;
+  my $current_group;
   my $it = BSE::Util::Iterate->new;
   return
     (
@@ -1133,9 +1135,28 @@ sub low_edit_tags {
      DevHelp::Tags->make_iterator2
      ([ \&iter_crumbs, $article, $articles ], 'crumb', 'crumbs' ),
      typename => \&tag_typename,
+     $it->make_iterator([ \&iter_groups, $request ], 
+                       'group', 'groups', \@groups, undef, undef,
+                       \$current_group),
+     ifGroupRequired => [ \&tag_ifGroupRequired, $article, \$current_group ],
     );
 }
 
+sub iter_groups {
+  my ($req) = @_;
+
+  require BSE::TB::SiteUserGroups;
+  BSE::TB::SiteUserGroups->admin_and_query_groups($req->cfg);
+}
+
+sub tag_ifGroupRequired {
+  my ($article, $rgroup) = @_;
+
+  $$rgroup or return 0;
+
+  $article->is_accessible_to($$rgroup);
+}
+
 sub edit_template {
   my ($self, $article, $cgi) = @_;
 
@@ -1404,6 +1425,16 @@ sub save_new {
       or $data{$col} = $self->default_value($req, \%data, $col);
   }
 
+  for my $col (qw/force_dynamic inherit_siteuser_rights/) {
+    if ($req->user_can("edit_add_field_$col", $parent)
+       && $cgi->param("save_$col")) {
+      $data{$col} = $cgi->param($col) ? 1 : 0;
+    }
+    else {
+      $data{$col} = $self->default_value($req, \%data, $col);
+    }
+  }
+
   for my $col (qw(release expire)) {
     $data{$col} = sql_date($data{$col});
   }
@@ -1558,8 +1589,36 @@ sub save {
     if defined $cgi->param('expire') && 
       $req->user_can('edit_field_edit_expire', $article);
   $article->{lastModified} =  now_sqldatetime();
-  if ($cgi->param('save_force_dynamic')) {
-    $article->{force_dynamic} = $cgi->param('force_dynamic') ? 1 : 0;
+  for my $col (qw/force_dynamic inherit_siteuser_rights/) {
+    if ($req->user_can("edit_field_edit_$col", $article)
+       && $cgi->param("save_$col")) {
+      $article->{$col} = $cgi->param($col) ? 1 : 0;
+    }
+  }
+
+# Added by adrian
+  my $user = $req->getuser;
+  $article->{lastModifiedBy} = $user ? $user->{logon} : '';
+# end adrian
+
+  my @save_group_ids = $cgi->param('save_group_id');
+  if ($req->user_can('edit_field_edit_group_id')
+      && @save_group_ids) {
+    require BSE::TB::SiteUserGroups;
+    my %groups = map { $_->{id} => $_ }
+      BSE::TB::SiteUserGroups->admin_and_query_groups($self->{cfg});
+    my %set = map { $_ => 1 } $cgi->param('group_id');
+    my %current = map { $_ => 1 } $article->group_ids;
+
+    for my $group_id (@save_group_ids) {
+      $groups{$group_id} or next;
+      if ($current{$group_id} && !$set{$group_id}) {
+       $article->remove_group_id($group_id);
+      }
+      elsif (!$current{$group_id} && $set{$group_id}) {
+       $article->add_group_id($group_id);
+      }
+    }
   }
 
   # this need to go last
@@ -1570,11 +1629,6 @@ sub save {
     $article->setLink($article_uri);
   }
 
-# Added by adrian
-  my $user = $req->getuser;
-  $article->{lastModifiedBy} = $user ? $user->{logon} : '';
-# end adrian
-
   $article->save();
 
   # if we changed dynamic status, we need to update it for the kids too
@@ -1651,6 +1705,7 @@ sub ampm_time {
       $ampm = 'PM';
     }
     else {
+      $hour = 12 if $hour == 0;
       $ampm = 'AM';
     }
     return sprintf("%02d:%02d:%02d $ampm", $hour, $minute, $second);
@@ -2794,6 +2849,8 @@ my %defaults =
    listed => 1,
    keyword => '',
    body => '<maximum of 64Kb>',
+   force_dynamic => 0,
+   inherit_siteuser_rights => 1,
   );
 
 sub default_value {
index db3fa57fb631cd4a6318c75bde97638762ab27a5..b4fed504d1c7521121d3c6c3e899707be10867c6 100644 (file)
@@ -37,12 +37,14 @@ sub valid_rules {
 sub remove {
   my ($self) = @_;
 
-  # remove any permissions and members for this group
-  print STDERR "** FIXME ", __FILE__, " ", __LINE__, "\n";
-
   # remove any members
   BSE::DB->single->run(siteuserGroupDeleteAllMembers => $self->{id});
 
+  # remove any article permissions
+  # note: this may leave an article dynamic that doesn't need to be
+  # but I don't care much
+  BSE::DB->single->run(siteuserGroupDeleteAllPermissions => $self->{id});
+
   $self->SUPER::remove();
 }
 
index 5265deb87664fa512d9cd8821892b4099839da67..c9c30c765764e9b8b4fc524847376063f5872e0d 100644 (file)
@@ -3,6 +3,37 @@ use strict;
 use base 'Squirrel::Table';
 use BSE::TB::SiteUserGroup;
 
+use constant SECT_QUERY_GROUPS => "Query Groups";
+use constant SECT_QUERY_GROUP_PREFIX => 'Query group ';
+
 sub rowClass { 'BSE::TB::SiteUserGroup' }
 
+sub admin_and_query_groups {
+  my ($class, $cfg) = @_;
+
+  my @groups = $class->all;
+
+  my $id = 1;
+  my $name;
+  while ($name = $cfg->entry(SECT_QUERY_GROUPS, $id)) {
+    my $group = $class->getQueryGroup($cfg, -$id);
+    $group and push @groups, $group;
+      
+    ++$id;
+  }
+
+  @groups;
+}
+
+sub getQueryGroup {
+  my ($class, $cfg, $id) = @_;
+
+  my $name = $cfg->entry(SECT_QUERY_GROUPS, -$id)
+    or return;
+  my $sql = $cfg->entry(SECT_QUERY_GROUP_PREFIX.$name, 'sql')
+    or return;
+
+  return { id => $id, name => $name, sql=>$sql };
+}
+
 1;
diff --git a/site/cgi-bin/modules/BSE/UI/Image.pm b/site/cgi-bin/modules/BSE/UI/Image.pm
new file mode 100644 (file)
index 0000000..ad040ed
--- /dev/null
@@ -0,0 +1,55 @@
+package BSE::UI::Image;
+use strict;
+use Articles;
+use Images;
+use BSE::Util::Tags qw(tag_hash);
+
+# we don't do anything fancy on dispatch yet, so don't use the 
+# dispatch classes
+sub dispatch {
+  my ($class, $req) = @_;
+
+  my $cgi = $req->cgi;
+  my $id = $cgi->param('id');
+  $id && $id =~ /^\d+$/
+    or return $class->error($req, "required id parameter not present or invalid");
+  my $article = Articles->getByPkey($id)
+    or return $class->error($req, "unknown article id $id");
+
+  my $image;
+  
+  if (defined(my $imid = $cgi->param('imid'))) {
+    $imid =~ /^\d+$/
+      or return $class->error($req, "Invalid imid supplied");
+    $image = Images->getByPkey($imid);
+
+    $image && $image->{articleId} == $article->{id}
+      or return $class->error($req, "Unknown image identifier supplied");
+  }
+  elsif (defined(my $imname = $cgi->param('imname'))) {
+    length $imname and $imname =~ /^\w+$/
+      or return $class->error($req, "Invalid imname supplied");
+    ($image) = Images->getBy(articleId=>$article->{id}, name=>$imname)
+      or return $class->error($req, "Unknown image name supplied");
+  }
+
+  my %acts;
+  %acts =
+    (
+     BSE::Util::Tags->static(),
+     article => [ \&tag_hash, $article ],
+     image => [ \&tag_hash, $image ],
+    );
+
+  return $req->response('image', \%acts);
+}
+
+# returns an error page
+sub error {
+  my ($class, $req, $msg) = @_;
+
+  require BSE::UI::Dispatch;
+  return BSE::UI::Dispatch->error($req, { error => $msg });
+}
+
+1;
index d45fa623f0b2aec3bade10c59df7d57ebd6c73a7..80f1f9c6159836c535ab0aa1252d96a4fc3d1573 100644 (file)
@@ -1,6 +1,7 @@
 package BSE::UI::Page;
 use strict;
 use Articles;
+use DevHelp::HTML qw(escape_uri);
 
 # we don't do anything fancy on dispatch yet, so don't use the 
 # dispatch classes
@@ -31,6 +32,20 @@ sub dispatch {
     or print STDERR "** page.pl called for non-dynamic article $id\n";
 
   my $cfg = $req->cfg;
+
+  unless ($class->has_access($req, $article)) {
+    if ($req->siteuser) {
+      return $class->error
+       ($req, "You do not have access to view this article");
+    }
+    else {
+      my $refresh = $article->{link};
+      my $logon =
+       $cfg->entry('site', 'url') . "/cgi-bin/user.pl?show_logon=1&r=".escape_uri($refresh)."&message=You+need+to+logon+to+view+this+article";
+      return BSE::Template->get_refresh($logon, $cfg);
+    }
+  }
+
   my $dynamic_path = $cfg->entryVar('paths', 'dynamic_cache');
   my $debug_jit = $cfg->entry('debug', 'jit_dynamic_regen');
   my $srcname = $dynamic_path . "/" . $article->{id} . ".html";
@@ -87,4 +102,64 @@ sub _generate_pregen {
   $content;
 }
 
+sub _have_group_access {
+  my ($req, $user, $group_ids, $membership) = @_;
+
+  if (grep $_ > 0, @$group_ids) {
+    $membership->{filled}
+      or %$membership = map { $_ => 1 } 'filled', $user->group_ids;
+    return 1
+      if grep $membership->{$_}, @$group_ids;
+  }
+  for my $query_id (grep $_ < 0, @$group_ids) {
+    require BSE::TB::SiteUserGroups;
+    my $group = BSE::TB::SiteUserGroups->getQueryGroup($req->cfg, $query_id)
+      or next;
+    my $rows = BSE::DB->single->dbh->selectall_arrayref($group->{sql}, { MaxRows=>1 }, $user->{id});
+    $rows && @$rows
+      and return 1;
+  }
+
+  return 0;
+}
+
+sub has_access {
+  my ($class, $req, $article, $user, $default, $membership) = @_;
+
+  defined $default or $default = 1;
+  defined $membership or $membership = {};
+
+  my @group_ids = $article->group_ids;
+  if ($article->{inherit_siteuser_rights}
+      && $article->{parentid} != -1) {
+    if (@group_ids) {
+      if (_have_group_access($req, $user, \@group_ids, $membership)) {
+       return 1;
+      }
+      else {
+       return $class->has_access($req, $article->parent, $user, 0);
+      }
+    }
+    else {
+      # ask parent
+      return $class->has_access($req, $article->parent, $user, $default);
+    }
+  }
+  else {
+    if (@group_ids) {
+      $user ||= $req->siteuser
+       or return 0;
+      if (_have_group_access($req, $user, \@group_ids, $membership)) {
+       return 1;
+      }
+      else {
+       return 0;
+      }
+    }
+    else {
+      return $default;
+    }
+  }
+}
+
 1;
index 1a4536275f861e2b53bdf6d17b3fdd8c359689c9..d8d351ada7b0d1d48623857bcf418d9db425fae6 100644 (file)
@@ -471,6 +471,7 @@ HTML
      },
      ifImage => sub { $_[0] >= 1 && $_[0] <= @images },
      ifImages => sub { @images },
+     image_index => sub { $image_index },
      BSE::Util::Tags->make_iterator(\@files, 'file', 'files'),
      BSE::Util::Tags->make_iterator(\@stepkids, 'stepkid', 'stepkids'),
      BSE::Util::Tags->make_iterator(\@allkids, 'allkid', 'allkids', \$allkids_index),
index 679970a34595bb658945ef5278ced3f2d9c264ef..6385a80e953bcb61bebbd4377364c93a50af4206 100644 (file)
@@ -10,6 +10,47 @@ Maybe I'll add some other bits here.
 
 =head1 CHANGES
 
+=head2 0.15_21
+
+=over
+
+=item *
+
+added image.pl, intended for image display popups, accepts article id
+parameter as I<id> and either an image id as I<imid> or an image name
+as I<imname>.
+
+=item *
+
+you can now add siteuser groups required to view an article.  Adding
+such access requirements forces an article to be generated
+dynamically.
+
+=item *
+
+added sql_statements table, used for BSE extensions.
+
+=item *
+
+error.tmpl is now generated correctly from error_base.tmpl
+
+=item *
+
+siteuser group management actions now correctly refresh to the URL
+supplied in the r parameter, if any.
+
+=item *
+
+minor patch to fix the error message displayed when attempting to save
+over a modified article (midnight to 1am times now displayed
+correctly) (supplied by Adrian Oldham)
+
+=item *
+
+added image_index tag to the display article tags
+
+=back
+
 =head2 0.15_20
 
 Applied a patch from Adrian Oldham:
index 46ae64eca5e3b0c5d8e6bd6eae8659310184a7a0..a225831a6c1559b69d6bad396f17349b9fa64bcd 100644 (file)
@@ -1233,6 +1233,34 @@ by data passed to that filter.
 
 See the documentation for each filter to configure the filters.
 
+=head2 [Query Groups]
+
+The key of each entry is the numeric identifier of a query group, the
+values are the name of the query group.  For example:
+
+  [query groups]
+  1=some name
+
+  [query group some name]
+  sql=select id from site_users where id = ? and name1 like '%some%'
+
+Each entry also has a corresponding [Query Group I<name>] section.
+
+=head2 [query group I<name>]
+
+This section corresponds to an entry in [Query Groups].
+
+=over
+
+=item sql
+
+This is an SQL statement.  One placeholder is required and is passed
+the siteuser id (primary key) of the user to be checked.  If this
+query returns I<any> rows then the user is considered part of the
+group.
+
+=back
+
 =head2 [inpho]
 
 This is used to configure the DevHelp::Payments::Inpho module.
index 125e4eb64d7cdda2ba656d05ae0feb135567d108..7248359c059c5f09cad1e66a5e9cca7cb2aa9ce3 100644 (file)
@@ -8,7 +8,9 @@
     Eq:><a href="<:article admin:>">See article</a><:eif Eq:> | <:eif:><:editParent:> 
   <:if Eq [article id] [cfg articles shop]:><a href="/cgi-bin/admin/shopadmin.pl">Manage
    catalogs</a> |<:or Eq:><:eif Eq:><:if New:><:or New:> <a href="<:script:>?id=<:article id:>&amp;_t=steps">Manage
-    step children/parents</a> | <!--//<a href="<:script:>?id=<:article id:>&amp;_t=options">Edit options</a> |//--><:eif New:></p>
+    step children/parents</a> | 
+<a href="<:script:>?id=<:article id:>&amp;_t=groups">Manage access</a> |
+<:eif New:></p>
 
   <h2><:articleType:> Details</h2>
 
               (comma separated)<:or:><: article threshold :><:eif:></td>
             <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit keywords:> <:error_img keyword:></td>
           </tr>
+          <tr> 
+            <th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Always Dynamic:</th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm force_dynamic:><input type="hidden" name="save_force_dynamic" value="1" /><input type="checkbox" name="force_dynamic" value="1" <:if Article force_dynamic :>checked="checked"<:or Article:><:eif Article:> />
+              <:or:><:ifArticle force_dynamic :>Yes<:or Article:>No<:eif Article:><:eif:></td>
+            <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit keywords:> <:error_img keyword:></td>
+          </tr>
 <:include admin/article_custom.tmpl optional:>
           <tr> 
             <th nowrap="nowrap" bgcolor="#FFFFFF" align="left" valign="top">Thumbnail image:</th>
index b9d29ed080af283e70709548020bc20a48b1437f..fe89870301f597d6e89c8b68161f7e4205804049 100644 (file)
@@ -17,7 +17,9 @@
 <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>
+  step children/parents</a> | 
+<a href="<:script:>?id=<:article id:>&amp;_t=groups">Manage access</a> |
+<:eif New:></p>
 
   <h2>Catalog Details</h2>
 
               (comma separated) </td>
             <td nowrap bgcolor="#FFFFFF"><:help catalog keywords:> <:error_img keyword:></td>
           </tr>
+          <tr> 
+            <th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Always Dynamic:</th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm force_dynamic:><input type="hidden" name="save_force_dynamic" value="1" /><input type="checkbox" name="force_dynamic" value="1" <:if Article force_dynamic :>checked="checked"<:or Article:><:eif Article:> />
+              <:or:><:ifArticle force_dynamic :>Yes<:or Article:>No<:eif Article:><:eif:></td>
+            <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit keywords:> <:error_img keyword:></td>
+          </tr>
 <:include admin/catalog_custom.tmpl optional:>
           <tr> 
             <th bgcolor="#FFFFFF" nowrap align="left" valign="top">Thumbnail image:</th>
diff --git a/site/templates/admin/edit_groups.tmpl b/site/templates/admin/edit_groups.tmpl
new file mode 100644 (file)
index 0000000..cef9e36
--- /dev/null
@@ -0,0 +1,52 @@
+<:wrap admin/xbase.tmpl title=>"Manage Access" :>
+<h1>Manage Access</h1>
+<:ifMessage:> 
+<p><b><:message:></b></p>
+<:or:><:eif:>
+
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> | <:if Match [article generator] "Product":><a href="/cgi-bin/admin/add.pl?id=<:article id:>">Edit
+    product</a> | <a href="/cgi-bin/admin/shopadmin.pl">Manage catalogs</a> <:or
+    Match:><:if Eq [article id] [cfg articles shop]:><a href="/cgi-bin/admin/add.pl?id=<:article id:>">Edit
+    shop</a><:or Eq:><a href="/cgi-bin/admin/add.pl?id=<:article id:>"><:ifMatch
+    [article generator] "Catalog":>Edit catalog<:or:>Edit article<:eif:></a><:eif
+    Eq:><:eif Match:> |</p>
+<h2><a name="groups"></a>Groups</h2>
+<form method="post" action="<:script:>">
+<input type="hidden" name="id" value="<:article id:>" />
+<table border="0" cellpadding="6" cellspacing="1">
+  <tr bgcolor="#FFFFFF"> 
+    <th>Group</th>
+    <th>Required</th>
+  </tr>
+<:if Groups:>
+<:iterator begin groups:>
+  <tr>
+    <td><:group name:></td>
+    <td>
+      <input type="hidden" name="save_group_id" value="<:group id:>" />
+      <input type="checkbox" name="group_id" value="<:group id:>" <:ifGroupRequired:>checked="checked" <:or:><:eif:>/>
+    </td>
+  </tr>
+<:iterator end groups:>
+<:or Groups:>
+  <tr>
+    <td colspan="2">You have no <a href="/cgi-bin/admin/siteusers.pl?a_grouplist=1">groups defined</a></td>
+  </tr>
+<:eif Groups:>
+  <tr>
+    <td colspan="2"><hr /></td>
+  </tr>
+  <tr>
+    <th>Inherit Parent groups</th>
+    <td>
+      <input type="hidden" name="save_inherit_siteuser_rights" value="1" />
+      <input type="checkbox" name="inherit_siteuser_rights" value="1" <:ifArticle inherit_siteuser_rights:>checked="checked"<:or:><:eif:> />
+    </td>
+  </tr>
+  <tr>
+   <td colspan="2">
+    <input type="submit" name="save" value="Save" />
+   </td>
+  </tr>
+      </table>
+</form>
\ No newline at end of file
index dce45da424f7e39a648e3656aaad53de8d6ee864..6446df06a9e8886ac5ec0c78f45d22b794013645 100644 (file)
@@ -14,7 +14,9 @@
    :> <a href="/cgi-bin/admin/add.pl?id=<:product id:>&_t=steps">Manage
       step parents</a> | <:if Product listed:> <a href="<:script:>?id=<:product id:>&hide=1&r=<:script:>?id=<:product id:>">Hide
       product</a> |<:or Product:> <a href="<:script:>?id=<:product id:>&unhide=1&r=<:script:>?id=<:product id:>">Show
-      product</a> |<:eif Product:><:or UserCan:><:eif UserCan:><:ifProduct listed:><:or:> Hidden<:eif:><:eif
+      product</a> |
+<a href="<:script:>?id=<:article id:>&amp;_t=groups">Manage access</a> |
+<:eif Product:><:or UserCan:><:eif UserCan:><:ifProduct listed:><:or:> Hidden<:eif:><:eif
       New:></p>
   <h2>Product Details</h2>
 <:ifNew:><:or:><:if Or [iadminuser_count] [iadmingroup_count]:>
             <td nowrap bgcolor="#FFFFFF"><:help product threshold:> <:error_img
             threshold:></td>
           </tr>
+          <tr> 
+            <th bgcolor="#FFFFFF" nowrap align="left"> Keywords: </th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm keyword:><input type="text" name="keyword" maxlength="255" size="60" value="<: old keyword default keyword :>"><:or:><: article threshold :><:eif:>
+              (comma separated) </td>
+            <td nowrap bgcolor="#FFFFFF"><:help catalog keywords:> <:error_img keyword:></td>
+          </tr>
+          <tr> 
+            <th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Always Dynamic:</th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm force_dynamic:><input type="hidden" name="save_force_dynamic" value="1" /><input type="checkbox" name="force_dynamic" value="1" <:if Article force_dynamic :>checked="checked"<:or Article:><:eif Article:> />
+              <:or:><:ifArticle force_dynamic :>Yes<:or Article:>No<:eif Article:><:eif:></td>
+            <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit keywords:> <:error_img keyword:></td>
+          </tr>
           <tr> 
             <th align="left" bgcolor="#FFFFFF">Options:</th>
             <td bgcolor="#FFFFFF"> 
index 04af70f998cba38191baf2b9822d2877ed4d010d..0b780b00d017d1fa62ff21b835d1dde7336ee4ef 100644 (file)
@@ -16,6 +16,7 @@
       seminar</a> |<:or Seminar:> <a href="<:script:>?id=<:seminar id:>&unhide=1&r=<:script:>?id=<:seminar id:>">Show
       seminar</a> |<:eif Seminar:><:or UserCan:><:eif UserCan:><:ifSeminar listed:><:or:> Hidden<:eif:>
 <a href="<:script:>?id=<:seminar id:>&amp;_t=semsessions">Manage Sessions</a> |
+<a href="<:script:>?id=<:article id:>&amp;_t=groups">Manage access</a> |
 <:eif
       New:></p>
   <h2>Seminar Details</h2>
               (<:alloptions:>)<:or:><:seminar options:><:eif:> </td>
             <td bgcolor="#FFFFFF"><:help product options:> <:error_img options:></td>
           </tr>
+          <tr> 
+            <th bgcolor="#FFFFFF" nowrap align="left"> Keywords: </th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm keyword:><input type="text" name="keyword" maxlength="255" size="60" value="<: old keyword default keyword :>"><:or:><: article threshold :><:eif:>
+              (comma separated) </td>
+            <td nowrap bgcolor="#FFFFFF"><:help catalog keywords:> <:error_img keyword:></td>
+          </tr>
+          <tr> 
+            <th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Always Dynamic:</th>
+            <td bgcolor="#FFFFFF" width="100%"> 
+              <:ifFieldPerm force_dynamic:><input type="hidden" name="save_force_dynamic" value="1" /><input type="checkbox" name="force_dynamic" value="1" <:if Article force_dynamic :>checked="checked"<:or Article:><:eif Article:> />
+              <:or:><:ifArticle force_dynamic :>Yes<:or Article:>No<:eif Article:><:eif:></td>
+            <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit keywords:> <:error_img keyword:></td>
+          </tr>
 <:include admin/seminar_custom.tmpl optional:>
           <tr> 
             <th nowrap align="left" bgcolor="#FFFFFF" valign="top">Thumbnail image:</th>
diff --git a/site/templates/error_base.tmpl b/site/templates/error_base.tmpl
new file mode 100644 (file)
index 0000000..d42673d
--- /dev/null
@@ -0,0 +1,20 @@
+<:wrap base.tmpl:> 
+<table width="100%" border="0" cellspacing="0" cellpadding="0">
+  <tr> 
+    <td height="24">&nbsp;&nbsp;<font face="Arial, Helvetica, sans-serif" size="4" color="#FF7F00"><b>Error</b></font></td>
+  </tr>
+  <tr> 
+    <td height="1" bgcolor="#999999"><img src="/images/trans_pixel.gif" width="24" height="1" border="0"></td>
+  </tr>
+  <tr> 
+    <td> <table width="100%" border="0" cellspacing="0" cellpadding="0">
+        <tr> 
+          <td width="100"><img src="/images/trans_pixel.gif" width="100" height="10" border="0"></td>
+          <td bgcolor="#999999" width="100%">&nbsp;<font face="Verdana, Arial, Helvetica, sans-serif" size="-2">/ 
+            <a href="<:ifAdmin:>/cgi-bin/admin/admin.pl?id=1<:or:>/<:eif:>"><font color="#FFFFFF">Home</font></a> 
+            /</font></td>
+        </tr>
+      </table></td>
+  </tr>
+</table>
+<p><br><br><br><font face="Verdana, Arial, Helvetica, sans-serif" size="-1"><:error:></font></p>
diff --git a/site/templates/image.tmpl b/site/templates/image.tmpl
new file mode 100644 (file)
index 0000000..623e37c
--- /dev/null
@@ -0,0 +1,3 @@
+<:wrap noartbase.tmpl title=>"[image alt]":>
+<div><img src="/images/<:image image:>" width="<:image width:>" height="<:image height:>" /></div>
+<p><:image alt:></p>
diff --git a/site/templates/noartbase.tmpl b/site/templates/noartbase.tmpl
new file mode 100644 (file)
index 0000000..aed457c
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >  
+<html><head><title>BSE - <:param title:></title>
+<link rel="stylesheet" href="/css/style-main.css" />
+</head>
+<body>
+<:wrap here:>
+</body></html>
index 1ea286533b4ff93bd4b6c7e937888e30bfa7b989..debf5b8a596d0575de3235a37d126bd5f1772d4f 100644 (file)
--- a/test.cfg
+++ b/test.cfg
@@ -97,8 +97,8 @@ bse siteuser images.logo=1
 bse siteuser image logo.description=Your Logo
 affiliate.subscription_required=affiliatepage
 
-editor.allow_thumb=1
-editor.thumbs_class=BSE::Thumb::Imager
+#editor.allow_thumb=1
+#editor.thumbs_class=BSE::Thumb::Imager
 
 default formmail validation.subject_width=40
 
@@ -162,3 +162,6 @@ bse location validation.postcode_description=Funky Postcode
 seminar.locations=1
 
 #report total_sales.bse_rights=blah|edit_foo,blah
+
+query groups.1=name starts with t
+query group name starts with t.sql=select id from site_users where id = ? and name1 like "t%"