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
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
# 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
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
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
-VERSION=0.15_20
+VERSION=0.15_21
DISTNAME=bse-$(VERSION)
DISTBUILD=$(DISTNAME)
DISTTAR=../$(DISTNAME).tar
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
+);
+
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)
[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.
--- /dev/null
+#!/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);
$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;
$_[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;
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 {
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 {
$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 {
}
}
- 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;
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(?, ?, ?, ?)',
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
);
my @stepparentpossibles;
my @files;
my $file_index;
+ my @groups;
+ my $current_group;
my $it = BSE::Util::Iterate->new;
return
(
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) = @_;
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});
}
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
$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
$ampm = 'PM';
}
else {
+ $hour = 12 if $hour == 0;
$ampm = 'AM';
}
return sprintf("%02d:%02d:%02d $ampm", $hour, $minute, $second);
listed => 1,
keyword => '',
body => '<maximum of 64Kb>',
+ force_dynamic => 0,
+ inherit_siteuser_rights => 1,
);
sub default_value {
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();
}
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;
--- /dev/null
+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;
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
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";
$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;
},
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),
=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:
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.
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:>&_t=steps">Manage
- step children/parents</a> | <!--//<a href="<:script:>?id=<:article id:>&_t=options">Edit options</a> |//--><:eif New:></p>
+ step children/parents</a> |
+<a href="<:script:>?id=<:article id:>&_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>
<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:>&_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>
--- /dev/null
+<: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
:> <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:>&_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">
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:>&_t=semsessions">Manage Sessions</a> |
+<a href="<:script:>?id=<:article id:>&_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>
--- /dev/null
+<:wrap base.tmpl:>
+<table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td height="24"> <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%"> <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>
--- /dev/null
+<:wrap noartbase.tmpl title=>"[image alt]":>
+<div><img src="/images/<:image image:>" width="<:image width:>" height="<:image height:>" /></div>
+<p><:image alt:></p>
--- /dev/null
+<?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>
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
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%"