site/templates/1/shop_multicat.tmpl
site/templates/1/sitemap.tmpl
# site/templates/admin/add_product.tmpl
+site/templates/admin/addattendee1.tmpl
+site/templates/admin/addattendee2.tmpl
site/templates/admin/addgroup.tmpl
site/templates/admin/adduser.tmpl
# site/templates/admin/article_custom.tmpl
site/templates/interest/askagain_base.tmpl
site/templates/interest/confirm_base.tmpl
site/templates/interest/error_base.tmpl
+site/templates/location.tmpl
site/templates/lowmap.tmpl
site/templates/mailconfirm.tmpl
site/templates/mailorder.tmpl
site/templates/printable/printable.tmpl
site/templates/printable/wap.tmpl
site/templates/search_base.tmpl
+site/templates/seminars/seminar.tmpl
site/templates/shop_help.tmpl
site/templates/shop_sect.tmpl
site/templates/shopitem.tmpl
-VERSION=0.15_14
+VERSION=0.15_15
DISTNAME=bse-$(VERSION)
DISTBUILD=$(DISTNAME)
DISTTAR=../$(DISTNAME).tar
-- transferred from the subscription
max_lapsed integer not null default 0,
+ -- session for a seminar
+ session_id integer not null default -1,
+
primary key (id),
index order_item_order(orderId, id)
);
BSE::Util::Tags->make_iterator(\@subs, 'subscription', 'subscriptions',
\$subindex),
BSE::Util::Tags->secure($req),
+ BSE::Util::Tags->admin(\%acts, $cfg),
message => sub { CGI::escapeHTML($message) },
recipient_count => [ \&tag_list_recipient_count, \@subs, \$subindex ],
);
getOrderItemByOrderId => 'select * from order_item where orderId = ?',
addOrder => 'insert orders values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
replaceOrder => 'replace orders values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
- addOrderItem => 'insert order_item values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ addOrderItem => 'insert order_item values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
getOrderByUserId => 'select * from orders where userId = ?',
deleteOrdersItems => 'delete from order_item where orderId = ?',
Seminars => <<SQL,
select ar.*, pr.*, se.*
from article ar, product pr, bse_seminars se
- where ar.id = pr.articleId and ar.id = se.articleId
+ where ar.id = pr.articleId and ar.id = se.seminar_id
SQL
addSeminar => 'insert bse_seminars values(?,?)',
replaceSeminar => 'replace bse_seminars values(?,?)',
select ar.*, pr.*, se.*
from article ar, product pr, bse_seminars se
where id = ? and ar.id = pr.articleId and ar.id = se.seminar_id
+SQL
+ 'Locations.seminarFuture' => <<SQL,
+select distinct lo.*
+ from bse_locations lo, bse_seminar_sessions ss
+where ss.seminar_id = ? and ss.when_at > ?
+ and ss.location_id = lo.id
+order by lo.description
+SQL
+ 'Locations.session_id' => <<SQL,
+select lo.*
+ from bse_locations lo, bse_seminar_sessions ss
+where lo.id = ss.location_id and ss.id = ?
SQL
seminarSessionInfo => <<SQL,
from bse_seminar_sessions se, bse_locations lo
where se.seminar_id = ? and se.location_id = lo.id
order by when_at desc
+SQL
+ seminarFutureSessionInfo => <<SQL,
+select se.*, lo.description, lo.room, lo.street1, lo.street2, lo.suburb,
+ lo.state, lo.country, lo.postcode, lo.public_notes
+ from bse_seminar_sessions se, bse_locations lo
+ where se.seminar_id = ? and se.when_at > ? and se.location_id = lo.id
+order by when_at desc
SQL
addSeminarSession => 'insert bse_seminar_sessions values(null,?,?,?,?)',
replaceSeminarSession => 'replace bse_seminar_sessions values(?,?,?,?,?)',
getSeminarSessionByLocation_idAndWhen_at => <<SQL,
select * from bse_seminar_sessions
where location_id = ? and when_at = ?
+SQL
+ getSeminarSessionBySeminar_id => <<SQL,
+select * from bse_seminar_sessions
+ where seminar_id = ?
SQL
'SeminarSessions.futureSessions' => <<SQL,
select * from bse_seminar_sessions
where seminar_id = ? and when_at >= ?
+SQL
+ 'SeminarSessions.futureSeminarLocation' => <<SQL,
+select *
+ from bse_seminar_sessions
+ where seminar_id = ? and location_id = ? and when_at > ?
SQL
'SiteUsers.sessionBookings' => <<SQL,
select su.* from site_users su, bse_seminar_bookings sb
select * from bse_seminar_bookings where session_id = ?
SQL
seminarSessionBookUser => <<SQL,
-insert bse_seminar_bookings values(?,?)
+insert bse_seminar_bookings values(?,?,?)
SQL
seminarSessionRollCallEntries => <<SQL,
select bo.roll_present, su.id, su.userId, su.name1, su.name2, su.email
from bse_seminar_bookings bo, site_users su
where bo.session_id = ? and bo.siteuser_id = su.id
SQL
- updateSessionRollPresent => <<SQL
+ updateSessionRollPresent => <<SQL,
update bse_seminar_bookings
set roll_present = ?
where session_id = ? and siteuser_id = ?
+SQL
+ userSeminarSessionBookings => <<SQL,
+select session_id
+ from bse_seminar_bookings sb, bse_seminar_sessions ss
+where ss.seminar_id = ? and ss.id = sb.session_id and siteuser_id = ?
SQL
);
custom_class($self->{cfg})
->article_validate($data, undef, $self->typename, $errors);
- if (!defined $data->{parentid} || $data->{parentid} eq '') {
- $errors->{parentid} = "Please select a parent";
- }
- elsif ($data->{parentid} !~ /^(?:-1|\d+)$/) {
- $errors->{parentid} = "Invalid parent selection (template bug)";
- }
-
return !keys %$errors;
}
my $msg;
my %errors;
+ if (!defined $data{parentid} || $data{parentid} eq '') {
+ $errors{parentid} = "Please select a parent";
+ }
+ elsif ($data{parentid} !~ /^(?:-1|\d+)$/) {
+ $errors{parentid} = "Invalid parent selection (template bug)";
+ }
$self->validate(\%data, $articles, \%errors)
or return $self->add_form($req, $articles, $msg, \%errors);
or $data{$col} = $self->default_value($req, \%data, $col);
}
- print STDERR "release cgi ", $cgi->param('release'), " data $data{release}\n";
+ for my $col (qw(release expire)) {
+ $data{$col} = sql_date($data{$col});
+ }
+
# these columns are handled a little differently
for my $col (qw(release expire threshold summaryLength )) {
$data{$col}
or $data{$col} = $self->default_value($req, \%data, $col);
}
- for my $col (qw(release expire)) {
- $data{$col} = sql_date($data{$col});
- }
-
shift @columns;
my $article = $table_object->add(@data{@columns});
use DevHelp::Date qw(dh_parse_date_sql dh_parse_time_sql);
use constant SECT_SEMSESSION_VALIDATION => 'BSE Seminar Session Validation';
use DevHelp::HTML qw(escape_html);
+use BSE::Util::Iterate;
sub article_actions {
my ($self) = @_;
);
}
-sub base_template_dirs {
- return ( "seminar" );
-}
-
sub edit_template {
my ($self, $article, $cgi) = @_;
return $self->refresh($article, $cgi, undef, "Roll saved");
}
+sub base_template_dirs {
+ return ( "seminars" );
+}
+
+sub extra_templates {
+ my ($self, $article) = @_;
+
+ my @extras;
+
+ my $extras = $self->{cfg}->entry('seminars', 'extra_templates');
+ push @extras, grep /\.(tmpl|html)$/i, split /,/, $extras
+ if $extras;
+
+ return @extras;
+}
+
1;
use BSE::TB::Seminars;
use DevHelp::HTML;
use BSE::Util::Tags qw(tag_hash);
+use BSE::Util::Iterate;
sub baseActs {
my ($self, $articles, $acts, $seminar, $embedded) = @_;
unless ($seminar->isa('BSE::TB::Seminar')) {
$seminar = BSE::TB::Seminars->getByPkey($seminar->{id});
}
+ my $it = BSE::Util::Iterate->new;
+ my $location;
return
(
$self->SUPER::baseActs($articles, $acts, $seminar, $embedded),
seminar => [ \&tag_hash, $seminar ],
admin => [ tag_admin => $self, $seminar, 'seminar', $embedded ],
+ $it->make_iterator([ \&iter_sessions, $seminar ], 'session', 'sessions'),
+ $it->make_iterator
+ ([ \&iter_locations, $seminar ], 'location', 'locations',
+ undef, undef, undef, \$location),
+ $it->make_iterator
+ ([ \&iter_location_sessions, $seminar, \$location ], 'location_session',
+ 'location_sessions', undef, undef, 'nocache'),
);
}
+sub iter_sessions {
+ my ($seminar) = @_;
+
+ $seminar->future_session_info;
+}
+
+sub iter_locations {
+ my ($seminar) = @_;
+
+ $seminar->future_locations;
+}
+
+sub iter_location_sessions {
+ my ($seminar, $rlocation) = @_;
+
+ $$rlocation or return;
+
+ $seminar->future_location_sessions($$rlocation);
+}
+
1;
use BSE::Util::Tags;
use BSE::CfgInfo qw(custom_class);
use Carp 'confess';
+use DevHelp::HTML qw(escape_html);
# returns a list of tags which display the cart details
sub shop_cart_tags {
require 'SiteUsers.pm';
$user = SiteUsers->getBy(userId=>$session->{userid});
}
-
+ my $sem_session;
+ my $location;
+ my $item;
+ my $product;
return
(
BSE::Util::Tags->basic($acts, $q, $cfg),
$option_index = -1;
@options = cart_item_opts($cart->[$item_index],
$cart_prods->[$item_index]);
+ undef $sem_session;
+ undef $location;
+ $item = $cart->[$item_index];
+ $product = $cart_prods->[$item_index];
return 1;
}
+ undef $item;
+ undef $sem_session;
+ undef $product;
+ undef $location;
return 0;
},
item =>
option => sub { CGI::escapeHTML($options[$option_index]{$_[0]}) },
ifOptions => sub { @options },
options => sub { nice_options(@options) },
+ session => [ \&tag_session, \$item, \$sem_session ],
+ location => [ \&tag_location, \$item, \$location ],
custom_class($cfg)
->checkout_actions($acts, $cart, $cart_prods, $session->{custom}, $q, $cfg),
);
}
+sub tag_session {
+ my ($ritem, $rsession, $arg) = @_;
+
+ $$ritem or return '';
+
+ $$ritem->{session_id} or return '';
+
+ unless ($$rsession) {
+ require BSE::TB::SeminarSessions;
+ $$rsession = BSE::TB::SeminarSessions->getByPkey($$ritem->{session_id})
+ or return '';
+ }
+
+ my $value = $$rsession->{$arg};
+ defined $value or return '';
+
+ escape_html($value);
+}
+
+sub tag_location {
+ my ($ritem, $rlocation, $arg) = @_;
+
+ $$ritem or return '';
+
+ $$ritem->{session_id} or return '';
+
+ unless ($$rlocation) {
+ require BSE::TB::Locations;
+ ($$rlocation) = BSE::TB::Locations->getSpecial(session_id => $$ritem->{session_id})
+ or return '';
+ }
+
+ my $value = $$rlocation->{$arg};
+ defined $value or return '';
+
+ escape_html($value);
+}
+
sub cart_item_opts {
my ($cart_item, $product) = @_;
sub columns {
return qw/id productId orderId units price wholesalePrice gst options
customInt1 customInt2 customInt3 customStr1 customStr2 customStr3
- title summary subscription_id subscription_period max_lapsed/;
+ title summary subscription_id subscription_period max_lapsed
+ session_id/;
}
1;
my ($self) = @_;
require BSE::TB::SeminarSessions;
- BSE::TB::SeminarSessions->getBy(session_id => $self->{id});
+ BSE::TB::SeminarSessions->getBy(seminar_id => $self->{id});
}
sub future_sessions {
BSE::DB->query(seminarSessionInfo => $self->{id});
}
+sub future_session_info {
+ my ($self) = @_;
+
+ BSE::DB->query(seminarFutureSessionInfo=>$self->{id}, now_sqldatetime());
+}
+
sub add_session {
my ($self, $when, $location) = @_;
return BSE::TB::SeminarSessions->add(@cols{@cols});
}
+sub future_locations {
+ my ($self) = @_;
+
+ require BSE::TB::Locations;
+ return BSE::TB::Locations->getSpecial
+ (seminarFuture => $self->{id}, now_sqldatetime());
+}
+
+sub future_location_sessions {
+ my ($self, $location) = @_;
+
+ require BSE::TB::SeminarSessions;
+ return BSE::TB::SeminarSessions->getSpecial
+ (futureSeminarLocation => $self->{id}, $location->{id}, now_sqldatetime());
+}
+
1;
BSE::DB->query(seminarSessionBookedIds => $self->{id});
for my $userid (@users_booked) {
unless ($conflicts{$userid}) {
- BSE::DB->run(seminarSessionBookUser => $other->{id}, $userid);
+ BSE::DB->run(seminarSessionBookUser => $other->{id}, $userid, 0);
}
}
BSE::DB->run(cancelSeminarSessionBookings => $self->{id});
BSE::DB->run(updateSessionRollPresent => $present, $self->{id}, $userid);
}
+sub add_attendee {
+ my ($self, $user, $present) = @_;
+
+ $present ||= 0;
+ my $user_id = ref $user ? $user->{id} : $user;
+
+ BSE::DB->run(seminarSessionBookUser => $self->{id}, $user_id, $present);
+}
+
1;
locdelete => 'bse_location_delete',
# detail => 'bse_subscr_detail',
# update => 'bse_subscr_update',
+ addattendseminar => 'bse_session_addattendee',
+ addattendsession => 'bse_session_addattendee',
+ addattendsave => 'bse_session_addattendee',
);
sub actions { \%rights }
return $r;
}
+sub req_addattendseminar {
+ my ($class, $req, $errors) = @_;
+
+ # make sure we're passed a valid siteuser_id
+ my $cgi = $req->cgi;
+ my $siteuser_id = $cgi->param('siteuser_id');
+ defined $siteuser_id && $siteuser_id =~ /^\d+$/
+ or return $class->req_loclist($req, { siteuser_id =>
+ "Missing or invalid siteuser_id" });
+ require SiteUsers;
+ my $siteuser = SiteUsers->getByPkey($siteuser_id)
+ or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
+ my $msg = $req->message($errors);
+ require BSE::TB::Seminars;
+ my @seminars = BSE::TB::Seminars->all;
+
+ my $it = BSE::Util::Iterate->new;
+ my %acts;
+ %acts =
+ (
+ BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
+ BSE::Util::Tags->admin(\%acts, $req->cfg),
+ BSE::Util::Tags->secure($req),
+ $it->make_iterator(undef, 'seminar', 'seminars', \@seminars),
+ siteuser => [ \&tag_hash, $siteuser ],
+ msg => $msg,
+ message => $msg,
+ error_img => [ \&tag_error_img, $req->cfg, $errors ],
+ );
+
+ return $req->dyn_response('admin/addattendee1.tmpl', \%acts);
+}
+
+sub req_addattendsession {
+ my ($class, $req, $errors) = @_;
+
+ # make sure we're passed a valid siteuser_id
+ my $cgi = $req->cgi;
+ my $siteuser_id = $cgi->param('siteuser_id');
+ defined $siteuser_id && $siteuser_id =~ /^\d+$/
+ or return $class->req_loclist($req, { siteuser_id =>
+ "Missing or invalid siteuser_id" });
+ require SiteUsers;
+ my $siteuser = SiteUsers->getByPkey($siteuser_id)
+ or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
+
+ # make sure we got a valid seminar
+ require BSE::TB::Seminars;
+ my $seminar_id = $cgi->param('seminar_id');
+ defined $seminar_id && $seminar_id =~ /^\d*$/
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Missing or invalid seminar_id" });
+ $seminar_id
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Please select a seminar" });
+ my $seminar = BSE::TB::Seminars->getByPkey($seminar_id)
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Unknown seminar_id" });
+ my $msg = $req->message($errors);
+
+ my @sessions = $seminar->session_info;
+ my %user_booked = map { $_=>1 }
+ $siteuser->seminar_sessions_booked($seminar_id);
+ @sessions = grep !$user_booked{$_->{id}}, @sessions;
+
+ my $it = BSE::Util::Iterate->new;
+ my %acts;
+ %acts =
+ (
+ BSE::Util::Tags->basic(\%acts, $req->cgi, $req->cfg),
+ BSE::Util::Tags->admin(\%acts, $req->cfg),
+ BSE::Util::Tags->secure($req),
+ siteuser => [ \&tag_hash, $siteuser ],
+ seminar => [ \&tag_hash, $seminar ],
+ msg => $msg,
+ message => $msg,
+ error_img => [ \&tag_error_img, $req->cfg, $errors ],
+ $it->make_iterator(undef, 'session', 'sessions', \@sessions),
+ );
+
+ return $req->dyn_response('admin/addattendee2.tmpl', \%acts);
+}
+
+sub req_addattendsave {
+ my ($class, $req, $errors) = @_;
+
+ # make sure we're passed a valid siteuser_id
+ my $cgi = $req->cgi;
+ my $siteuser_id = $cgi->param('siteuser_id');
+ defined $siteuser_id && $siteuser_id =~ /^\d+$/
+ or return $class->req_loclist($req, { siteuser_id =>
+ "Missing or invalid siteuser_id" });
+ require SiteUsers;
+ my $siteuser = SiteUsers->getByPkey($siteuser_id)
+ or return $class->req_loclist($req, { siteuser_id => "Unknown siteuser_id" });
+
+ # make sure we got a valid seminar
+ require BSE::TB::Seminars;
+ my $seminar_id = $cgi->param('seminar_id');
+ defined $seminar_id && $seminar_id =~ /^\d*$/
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Missing or invalid seminar_id" });
+ $seminar_id
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Please select a seminar" });
+ my $seminar = BSE::TB::Seminars->getByPkey($seminar_id)
+ or return $class->req_addattendseminar
+ ($req, { seminar_id => "Unknown seminar_id" });
+ my $msg = $req->message($errors);
+
+ # make sure we get a valid session
+ require BSE::TB::SeminarSessions;
+ my $session_id = $cgi->param('session_id');
+ defined $session_id && $session_id =~ /^\d*$/
+ or return $class->req_addattendsession
+ ($req, { session_id => "Missing or invalid session_id" });
+ $session_id
+ or return $class->req_addattendsession
+ ($req, { session_id => "Please select a session" });
+ my $session = BSE::TB::SeminarSessions->getByPkey($session_id)
+ or return $class->req_addattendsession
+ ($req, { session_id => "Unknown session_id" });
+
+ eval {
+ $session->add_attendee($siteuser, 1);
+ };
+ if ($@) {
+ if ($@ =~ /duplicate/i) {
+ return $class->req_addattendsession
+ ($req, { session_id => "User already booked for this session" });
+ }
+ }
+
+ my $r = $cgi->param('r');
+ unless ($r) {
+ $r = "/cgi-bin/admin/siteusers.pl?a_edit=1&id=" . $siteuser->{id};
+ }
+ print STDERR "refresh $r\n";
+
+ return BSE::Template->get_refresh($r, $req->cfg);
+}
+
1;
use BSE::TB::Orders;
use BSE::TB::OrderItems;
use BSE::Mail;
-use BSE::Util::Tags qw(tag_error_img);
+use BSE::Util::Tags qw(tag_error_img tag_hash);
use Products;
+use BSE::TB::Seminars;
use DevHelp::Validate qw(dh_validate dh_validate_hash);
use Digest::MD5 'md5_hex';
show_payment => 1,
payment => 1,
orderdone => 1,
+ location => 1,
);
my %field_map =
my $quantity = $cgi->param('quantity');
$quantity ||= 1;
my $product;
- $product = Products->getByPkey($addid) if $addid;
+ if ($addid) {
+ $product = BSE::TB::Seminars->getByPkey($addid);
+ $product ||= Products->getByPkey($addid);
+ }
$product or
return $class->req_cart($req, "Cannot find product $addid"); # oops
$quantity =~ /^\d+$/
or return $class->req_cart($req, "Invalid quantity");
+ my %extras;
+ if ($product->isa('BSE::TB::Seminar')) {
+ # you must be logged on to add a seminar
+ unless ($user) {
+ return $class->_refresh_logon
+ ($req, "You must be logged on to add seminars to your cart",
+ 'seminarlogon', $r);
+ }
+
+ # get and validate the session
+ my $session_id = $cgi->param('session_id');
+ defined $session_id
+ or return $class->req_cart($req, "Please select a session when adding a seminar");
+ $session_id =~ /^\d+$/
+ or return $class->req_cart($req, "Invalid session_id supplied");
+ require BSE::TB::SeminarSessions;
+ my $session = BSE::TB::SeminarSessions->getByPkey($session_id)
+ or return $class->req_cart($req, "Unknown session id supplied");
+ $session->{seminar_id} == $addid
+ or return $class->req_cart($req, "Session not for this seminar");
+
+ # check if the user is already booked for this session
+ grep($_ == $session_id, $user->seminar_sessions_booked($addid))
+ and return $class->req_cart($req, "You are already booked for this session");
+
+ $extras{session_id} = $session_id;
+ }
+
$req->session->{cart} ||= [];
my @cart = @{$req->session->{cart}};
productId => $addid,
units => $quantity,
price=>$product->{retailPrice},
- options=>$options
+ options=>$options,
+ %extras,
};
$req->session->{cart} = \@cart;
if ($sub) {
$subscribing_to{$sub->{text_id}} = $sub;
}
+
+ if ($item->{session_id}) {
+ my $user = $req->siteuser;
+ require BSE::TB::SeminarSessions;
+ my $session = BSE::TB::SeminarSessions->getByPkey($item->{session_id});
+ eval {
+ $session->add_attendee($user, 0);
+ };
+ }
}
$order->{ccOnline} = 0;
my $item_index = -1;
my @options;
my $option_index;
+ my $item;
+ my $product;
+ my $sem_session;
+ my $location;
my %acts;
%acts =
(
$option_index = -1;
@options = cart_item_opts($items[$item_index],
$products[$item_index]);
+ undef $sem_session;
+ undef $location;
+ $item = $items[$item_index];
+ $product = $products[$item_index];
return 1;
}
+ undef $item;
+ undef $sem_session;
+ undef $product;
+ undef $location;
return 0;
},
item=> sub { escape_html($showitems[$item_index]{$_[0]}); },
options => sub { nice_options(@options) },
ifPayment => [ \&tag_ifPayment, $order->{paymentType}, \%types_by_name ],
#ifSubscribingTo => [ \&tag_ifSubscribingTo, \%subscribing_to ],
+ session => [ \&tag_session, \$item, \$sem_session ],
+ location => [ \&tag_location, \$item, \$location ],
);
for my $type (@pay_types) {
my $id = $type->{id};
return $req->response('checkoutfinal', \%acts);
}
+sub tag_session {
+ my ($ritem, $rsession, $arg) = @_;
+
+ $$ritem or return '';
+
+ $$ritem->{session_id} or return '';
+
+ unless ($$rsession) {
+ require BSE::TB::SeminarSessions;
+ $$rsession = BSE::TB::SeminarSessions->getByPkey($$ritem->{session_id})
+ or return '';
+ }
+
+ my $value = $$rsession->{$arg};
+ defined $value or return '';
+
+ escape_html($value);
+}
+
+sub tag_location {
+ my ($ritem, $rlocation, $arg) = @_;
+
+ $$ritem or return '';
+
+ $$ritem->{session_id} or return '';
+
+ unless ($$rlocation) {
+ require BSE::TB::Locations;
+ ($$rlocation) = BSE::TB::Locations->getSpecial(session_id => $$ritem->{session_id})
+ or return '';
+ }
+
+ my $value = $$rlocation->{$arg};
+ defined $value or return '';
+
+ escape_html($value);
+}
+
sub tag_ifPayment {
my ($payment, $types_by_name, $args) = @_;
sub action_prefix { '' }
+sub req_location {
+ my ($class, $req) = @_;
+
+ require BSE::TB::Locations;
+ my $cgi = $req->cgi;
+ my $location_id = $cgi->param('location_id');
+ my $location;
+ if (defined $location_id && $location_id =~ /^\d$/) {
+ $location = BSE::TB::Locations->getByPkey($location_id);
+ my %acts;
+ %acts =
+ (
+ BSE::Util::Tags->static(\%acts, $req->cfg),
+ location => [ \&tag_hash, $location ],
+ );
+
+ return $req->response('location', \%acts);
+ }
+ else {
+ return
+ {
+ type=>BSE::Template->get_type($req->cfg, 'error'),
+ content=>"Missing or invalid location_id",
+ };
+ }
+}
+
1;
package DevHelp::Date;
use strict;
-use Exporter 'import';
-use vars qw(@EXPORT_OK %EXPORT_TAGS);
+require Exporter;
+use vars qw(@EXPORT_OK %EXPORT_TAGS @ISA);
+@ISA = qw(Exporter);
@EXPORT_OK =
qw(dh_parse_date dh_parse_date_sql dh_parse_time dh_parse_time_sql);
%EXPORT_TAGS =
return $self->{disabled};
}
+sub seminar_sessions_booked {
+ my ($self, $seminar_id) = @_;
+
+ return map $_->{session_id},
+ BSE::DB->query(userSeminarSessionBookings => $seminar_id, $self->{id});
+}
+
1;
my $result = BSE::UI::Shop->dispatch($req);
BSE::Template->output_result($req, $result);
-
-
-# use Products;
-# use Product;
-# use Constants qw(:shop $CGI_URI);
-# use BSE::Template;
-# use CGI::Cookie;
-# use BSE::WebUtil qw(refresh_to);
-# use BSE::CfgInfo qw(custom_class);
-# use BSE::Mail;
-# use BSE::Shop::Util qw/shop_cart_tags cart_item_opts nice_options total
-# basic_tags load_order_fields need_logon get_siteuser
-# payment_types/;
-# use BSE::Session;
-# use BSE::Cfg;
-# use BSE::Util::Tags qw(tag_hash);
-# use DevHelp::HTML;
-
-# my $cfg = BSE::Cfg->new();
-
-# my $subject = $cfg->entry('shop', 'subject', $SHOP_MAIL_SUBJECT);
-
-# # our PGP passphrase
-# my $passphrase = $SHOP_PASSPHRASE;
-
-# # the class we use to perform encryption
-# # we can change this to switch between GnuPG and PGP
-# my $crypto_class = $SHOP_CRYPTO;
-
-# # id of the private key to use for signing
-# # leave as undef to use your default key
-# my $signing_id = $SHOP_SIGNING_ID;
-
-# # location of PGP
-# my $pgpe = $SHOP_PGPE;
-# my $pgp = $SHOP_PGP;
-# my $gpg = $SHOP_GPG;
-
-# my $from = $cfg->entry('shop', 'from', $SHOP_FROM);
-
-# my $toName = $cfg->entry('shop', 'to_name', $SHOP_TO_NAME);
-# my $toEmail= $cfg->entry('shop', 'to_email', $SHOP_TO_EMAIL);
-
-# use constant PAYMENT_CC => 0;
-# use constant PAYMENT_CHEQUE => 1;
-# use constant PAYMENT_CALLME => 2;
-
-# my $urlbase = $cfg->entryVar('site', 'url');
-# my $securlbase = $cfg->entryVar('site', 'secureurl');
-# my %session;
-# BSE::Session->tie_it(\%session, $cfg);
-
-# # this shouldn't be necessary, but it stopped working elsewhere and this
-# # fixed it
-# END {
-# untie %session;
-# }
-
-# if (!exists $session{cart}) {
-# $session{cart} = [];
-# }
-
-# # the keys here are the names of the buttons on the various forms
-# # we also have 'delete_<number>' buttons.
-# my %steps =
-# (
-# add=>\&add_item,
-# cart=>\&show_cart,
-# checkout=>\&checkout,
-# checkupdate => \&checkupdate,
-# recheckout => sub { checkout('', 1); },
-# confirm => \&checkout_confirm,
-# recalc=>\&recalc,
-# recalculate=>\&recalc,
-# purchase=>\&purchase,
-# #prePurchase=>\&prePurchase,
-# );
-
-# for my $key (keys %steps) {
-# if (param($key) or param("$key.x")) {
-# $steps{$key}->();
-# exit;
-# }
-# }
-
-# for my $key (param()) {
-# if ($key =~ /^delete_(\d+)/) {
-# remove_item($1);
-# exit;
-# }
-# }
-
-# show_cart();
-
-# sub add_item {
-# my $addid = param('id');
-# $addid ||= '';
-# my $quantity = param('quantity');
-# $quantity ||= 1;
-# my $product;
-# $product = Products->getByPkey($addid) if $addid;
-# $product or return show_cart("Cannot find product $addid"); # oops
-
-# # collect the product options
-# my @options;
-# my @opt_names = split /,/, $product->{options};
-# my @not_def;
-# for my $name (@opt_names) {
-# my $value = param($name);
-# push @options, $value;
-# unless (defined $value) {
-# push @not_def, $name;
-# }
-# }
-# @not_def
-# and return show_cart("Some product options (@not_def) not supplied");
-# my $options = join(",", @options);
-
-# # the product must be non-expired and listed
-# use BSE::Util::SQL qw(now_sqldate);
-# (my $comp_release = $product->{release}) =~ s/ .*//;
-# (my $comp_expire = $product->{expire}) =~ s/ .*//;
-# my $today = now_sqldate();
-# $comp_release le $today
-# or return show_cart("Product has not been released yet");
-# $today le $comp_expire
-# or return show_cart("Product has expired");
-# $product->{listed} or return show_cart("Product not available");
-
-# # used to refresh if a logon is needed
-# my $r = $securlbase . $ENV{SCRIPT_NAME} . "?add=1&id=$addid";
-# for my $opt_index (0..$#opt_names) {
-# $r .= "&$opt_names[$opt_index]=".escape_uri($options[$opt_index]);
-# }
-
-# my $user = get_siteuser(\%session, $cfg, $CGI::Q);
-# # need to be logged on if it has any subs
-# if ($product->{subscription_id} != -1) {
-# if ($user) {
-# my $sub = $product->subscription;
-# if ($product->is_renew_sub_only) {
-# unless ($user->subscribed_to_grace($sub)) {
-# return show_cart("This product can only be used to renew your subscription to $sub->{title} and you are not subscribed nor within the renewal grace period");
-# }
-# }
-# elsif ($product->is_start_sub_only) {
-# if ($user->subscribed_to_grace($sub)) {
-# return show_cart("This product can only be used to start your subscription to $sub->{title} and you are already subscribed or within the grace period");
-# }
-# }
-# }
-# else {
-# refresh_logon("You must be logged on to add this product to your cart",
-# 'prodlogon', $r);
-# return;
-# }
-# }
-# if ($product->{subscription_required} != -1) {
-# my $sub = $product->subscription_required;
-# if ($user) {
-# unless ($user->subscribed_to($sub)) {
-# show_cart("You must be subscribed to $sub->{title} to purchase this product");
-# return;
-# }
-# }
-# else {
-# # we want to refresh back to adding the item to the cart if possible
-# refresh_logon("You must be logged on and subscribed to $sub->{title} to add this product to your cart",
-# 'prodlogonsub', $r);
-# return;
-# }
-# }
-
-# # we need a natural integer quantity
-# $quantity =~ /^\d+$/
-# or return show_cart("Invalid quantity");
-
-# my @cart = @{$session{cart}};
-
-# # if this is is already present, replace it
-# @cart = grep { $_->{productId} ne $addid || $_->{options} ne $options }
-# @cart;
-# push(@cart, { productId => $addid, units => $quantity,
-# price=>$product->{retailPrice},
-# options=>$options });
-
-# $session{cart} = \@cart;
-# show_cart();
-# }
-
-# sub show_cart {
-# my ($msg) = @_;
-# my @cart = @{$session{cart}};
-# my @cart_prods = map { Products->getByPkey($_->{productId}) } @cart;
-# my $item_index = -1;
-# my @options;
-# my $option_index;
-
-# $session{custom} ||= {};
-# my %custom_state = %{$session{custom}};
-
-# my $cust_class = custom_class($cfg);
-# $cust_class->enter_cart(\@cart, \@cart_prods, \%custom_state, $cfg);
-# $msg = '' unless defined $msg;
-# $msg = CGI::escapeHTML($msg);
-
-# my %acts;
-# %acts =
-# (
-# $cust_class->cart_actions(\%acts, \@cart, \@cart_prods, \%custom_state,
-# $cfg),
-# shop_cart_tags(\%acts, \@cart, \@cart_prods, \%session, $CGI::Q, $cfg,
-# 'cart'),
-# basic_tags(\%acts),
-# msg => $msg,
-# );
-# $session{custom} = \%custom_state;
-
-# page('cart.tmpl', \%acts);
-# }
-
-# sub update_quantities {
-# my @cart = @{$session{cart}};
-# for my $index (0..$#cart) {
-# my $new_quantity = param("quantity_$index");
-# if (defined $new_quantity) {
-# if ($new_quantity =~ /^\s*(\d+)/) {
-# $cart[$index]{units} = $1;
-# }
-# elsif ($new_quantity =~ /^\s*$/) {
-# $cart[$index]{units} = 0;
-# }
-# }
-# }
-# @cart = grep { $_->{units} != 0 } @cart;
-# $session{cart} = \@cart;
-# $session{custom} ||= {};
-# my %custom_state = %{$session{custom}};
-# custom_class($cfg)->recalc($CGI::Q, \@cart, [], \%custom_state, $cfg);
-# $session{custom} = \%custom_state;
-# }
-
-# sub recalc {
-# update_quantities();
-# show_cart();
-# }
-
-# sub remove_item {
-# my ($index) = @_;
-# my @cart = @{$session{cart}};
-# if ($index >= 0 && $index < @cart) {
-# splice(@cart, $index, 1);
-# }
-# $session{cart} = \@cart;
-
-# refresh_to($ENV{SCRIPT_NAME});
-# }
-
-# sub checkupdate {
-# my @cart = @{$session{cart}};
-# my @cart_prods = map { Products->getByPkey($_->{productId}) } @cart;
-# $session{custom} ||= {};
-# my %custom_state = %{$session{custom}};
-# custom_class($cfg)
-# ->checkout_update($CGI::Q, \@cart, \@cart_prods, \%custom_state, $cfg);
-# $session{custom} = \%custom_state;
-
-# checkout("", 1);
-# }
-
-# sub tag_checkedPayment {
-# my ($payment, $types_by_name, $args) = @_;
-
-# my $type = $args;
-# if ($type !~ /^\d+$/) {
-# return '' unless $types_by_name->{$type};
-# $type = $types_by_name->{$type};
-# }
-
-# return $payment == $type ? 'checked="checked"' : '';
-# }
-
-# sub tag_ifPayments {
-# my ($enabled, $types_by_name, $args) = @_;
-
-# my $type = $args;
-# if ($type !~ /^\d+$/) {
-# return '' unless $types_by_name->{$type};
-# $type = $types_by_name->{$type};
-# }
-
-# my @found = grep $_ == $type, @$enabled;
-
-# return scalar @found;
-# }
-
-# # display the checkout form
-# # can also be called with an error message and a flag to fillin the old
-# # values for the form elements
-# sub checkout {
-# my ($message, $olddata) = @_;
-
-# $message = '' unless defined $message;
-
-# update_quantities();
-# my @cart = @{$session{cart}};
-
-# @cart or return show_cart();
-
-# my @cart_prods = map { Products->getByPkey($_->{productId}) } @cart;
-
-# if (my ($msg, $id) = need_logon($cfg, \@cart, \@cart_prods, \%session, $CGI::Q)) {
-# refresh_logon($msg, $id);
-# return;
-# }
-
-# my $user = get_siteuser(\%session, $cfg, $CGI::Q);
-
-# $session{custom} ||= {};
-# my %custom_state = %{$session{custom}};
-
-# my $cust_class = custom_class($cfg);
-# $cust_class->enter_cart(\@cart, \@cart_prods, \%custom_state, $cfg);
-
-# my $noencrypt = $cfg->entryBool('shop', 'noencrypt', 0);
-
-# my @pay_types = payment_types($cfg);
-# my @payment_types = map $_->{id}, grep $_->{enabled}, @pay_types;
-# my %types_by_name = map { $_->{name} => $_->{id} } @pay_types;
-# if ($noencrypt) {
-# @payment_types = grep $_ ne PAYMENT_CC, @payment_types;
-# @payment_types or @payment_types = ( PAYMENT_CALLME );
-# }
-# else {
-# @payment_types or @payment_types = ( PAYMENT_CC );
-# }
-# @payment_types = sort { $a <=> $b } @payment_types;
-# my %payment_types = map { $_=> 1 } @payment_types;
-# my $payment;
-# $olddata and $payment = param('paymentType');
-# defined $payment or $payment = $payment_types[0];
-
-# my $affiliate_code = $session{affiliate_code};
-# defined $affiliate_code or $affiliate_code = '';
-
-# my $item_index = -1;
-# my @options;
-# my $option_index;
-# my %acts;
-# %acts =
-# (
-# shop_cart_tags(\%acts, \@cart, \@cart_prods, \%session, $CGI::Q, $cfg,
-# 'checkout'),
-# basic_tags(\%acts),
-# message => sub { $message },
-# old =>
-# sub {
-# my $value;
-
-# if ($olddata) {
-# $value = param($_[0]);
-# unless (defined $value) {
-# $value = $user->{$_[0]}
-# if $user;
-# }
-# }
-# else {
-# $value = $user && defined $user->{$_[0]} ? $user->{$_[0]} : '';
-# }
-
-# defined $value or $value = '';
-# CGI::escapeHTML($value);
-# },
-# $cust_class->checkout_actions(\%acts, \@cart, \@cart_prods,
-# \%custom_state, $CGI::Q, $cfg),
-# ifMultPaymentTypes => @payment_types > 1,
-# ifUser => defined $user,
-# user => $user ? [ \&tag_hash, $user ] : '',
-# checkedPayment => [ \&tag_checkedPayment, $payment, \%types_by_name ],
-# ifPayments => [ \&tag_ifPayments, \@payment_types, \%types_by_name ],
-# affiliate_code => escape_html($affiliate_code),
-# );
-# for my $type (@pay_types) {
-# my $id = $type->{id};
-# my $name = $type->{name};
-# $acts{"if${name}Payments"} = exists $payment_types{$id};
-# $acts{"if${name}FirstPayment"} = $payment_types[0] == $id;
-# $acts{"checkedIfFirst$name"} = $payment_types[0] == $id ? "checked " : "";
-# $acts{"checkedPayment$name"} = $payment == $id ? 'checked="checked" ' : "";
-# }
-# $session{custom} = \%custom_state;
-
-# page('checkout.tmpl', \%acts);
-# }
-
-# # displays the data entered by the user so they can either confirm the
-# # details or redisplay the checkout page
-# sub checkout_confirm {
-# my %order;
-# my $error;
-
-# my @cart_prods;
-# unless (load_order_fields(0, $CGI::Q, \%order, \%session, \@cart_prods,
-# \$error)) {
-# return checkout($error, 1);
-# }
-# ++$session{changed};
-# my @cart = @{$session{cart}};
-# # display the confirmation page
-# my %acts;
-# %acts =
-# (
-# order => sub { CGI::escapeHTML($order{$_[0]}) },
-# shop_cart_tags(\%acts, \@cart, \@cart_prods, \%session, $CGI::Q, $cfg,
-# 'confirm'),
-# basic_tags(\%acts),
-# old =>
-# sub {
-# my $value = param($_[0]);
-# defined $value or $value = '';
-# CGI::escapeHTML($value);
-# },
-# );
-# page('checkoutconfirm.tmpl', \%acts);
-# }
-
-# sub tag_ifPayment {
-# my ($payment, $types_by_name, $args) = @_;
-
-# my $type = $args;
-# if ($type !~ /^\d+$/) {
-# return '' unless $types_by_name->{$type};
-# $type = $types_by_name->{$type};
-# }
-
-# return $payment == $type;
-# }
-
-# # the real work
-# sub purchase {
-# $from && $from =~ /.\@./
-# or return checkout("Configuration error: shop from address not set", 1);
-# $toEmail && $toEmail =~ /.\@./
-# or return checkout("Configuration error: shop to_email address not set", 1);
-
-# # some basic validation, in case the user switched off javascript
-# my $cust_class = custom_class($cfg);
-# my @required =
-# $cust_class->required_fields($CGI::Q, $session{custom}, $cfg);
-
-# my $noencrypt = $cfg->entryBool('shop', 'noencrypt', 0);
-
-# my @pay_types = payment_types($cfg);
-# my %pay_types = map { $_->{id} => $_ } @pay_types;
-# my %types_by_name = map { $_->{name} => $_->{id} } @pay_types;
-# #use Data::Dumper;
-# #print STDERR Dumper \%pay_types;
-# my @payment_types = map $_->{id}, grep $_->{enabled}, @pay_types;
-# if ($noencrypt) {
-# @payment_types = grep $_ ne PAYMENT_CC, @payment_types;
-# @payment_types or @payment_types = ( PAYMENT_CALLME );
-# }
-# else {
-# @payment_types or @payment_types = ( PAYMENT_CC );
-# }
-# @payment_types = sort { $a <=> $b } @payment_types;
-# my %payment_types = map { $_=> 1 } @payment_types;
-
-# my $paymentType = param('paymentType');
-# defined $paymentType or $paymentType = $payment_types[0];
-# $payment_types{$paymentType}
-# or return checkout("Invalid payment type");
-
-# push @required, @{$pay_types{$paymentType}{require}};
-
-# for my $field (@required) {
-# my $display = $cfg->entry('shop', "display_$field", $field);
-# defined(param($field)) && length(param($field))
-# or return checkout("Field $display is required", 1);
-# }
-# defined(param('email')) && param('email') =~ /.\@./
-# or return checkout("Please enter a valid email address", 1);
-# if ($paymentType == PAYMENT_CC) {
-# defined(param('cardNumber')) && param('cardNumber') =~ /^\d+$/
-# or return checkout("Please enter a credit card number", 1);
-# }
-
-# use BSE::TB::Orders;
-# use BSE::TB::OrderItems;
-
-# # map some form fields to order field names
-# my %field_map =
-# (
-# name1 => 'delivFirstName',
-# name2 => 'delivLastName',
-# address => 'delivStreet',
-# city => 'delivSuburb',
-# postcode => 'delivPostCode',
-# state => 'delivState',
-# country => 'delivCountry',
-# email => 'emailAddress',
-# cardHolder => 'ccName',
-# cardType => 'ccType',
-# );
-# # paranoia, don't store these
-# my %nostore =
-# (
-# cardNumber => 1,
-# cardExpiry => 1,
-# );
-# my %order;
-# my @cart = @{$session{cart}};
-# @cart or return show_cart('You have no items in your shopping cart');
-
-# # so we can quickly check for columns
-# my @columns = BSE::TB::Order->columns;
-# my %columns;
-# @columns{@columns} = @columns;
-
-# for my $field (param()) {
-# $order{$field_map{$field} || $field} = param($field)
-# unless $nostore{$field};
-# }
-
-# my $ccNumber = param('cardNumber');
-# defined $ccNumber or $ccNumber = '';
-# my $ccExpiry = param('cardExpiry');
-# defined $ccExpiry or $ccExpiry = '';
-# my $affiliate_code = $session{affiliate_code};
-# defined $affiliate_code && length $affiliate_code
-# or $affiliate_code = param('affiliate_code');
-# defined $affiliate_code or $affiliate_code = '';
-# $order{affiliate_code} = $affiliate_code;
-
-# use Digest::MD5 'md5_hex';
-# $ccNumber =~ tr/0-9//cd;
-# $order{ccNumberHash} = md5_hex($ccNumber);
-# $order{ccExpiryHash} = md5_hex($ccExpiry);
-
-# # work out totals
-# $order{total} = 0;
-# $order{gst} = 0;
-# $order{wholesale} = 0;
-# $order{shipping_cost} = 0;
-# my @products;
-# my $today = now_sqldate();
-# for my $item (@cart) {
-# my $product = Products->getByPkey($item->{productId});
-# # double check that it's still a valid product
-# if (!$product) {
-# return show_cart("Product $item->{productId} not found");
-# }
-# else {
-# (my $comp_release = $product->{release}) =~ s/ .*//;
-# (my $comp_expire = $product->{expire}) =~ s/ .*//;
-# $comp_release le $today
-# or return show_cart("'$product->{title}' has not been released yet");
-# $today le $comp_expire
-# or return show_cart("'$product->{title}' has expired");
-# $product->{listed}
-# or return show_cart("'$product->{title}' not available");
-# }
-# push(@products, $product); # used in page rendering
-# @$item{qw/price wholesalePrice gst/} =
-# @$product{qw/retailPrice wholesalePrice gst/};
-# $order{total} += $item->{price} * $item->{units};
-# $order{wholesale} += $item->{wholesalePrice} * $item->{units};
-# $order{gst} += $item->{gst} * $item->{units};
-# }
-
-# if (my ($msg, $id) = need_logon($cfg, \@cart, \@products, \%session, $CGI::Q)) {
-# refresh_logon($msg, $id);
-# return;
-# }
-
-# use BSE::Util::SQL qw(now_sqldatetime);
-# $order{orderDate} = now_sqldatetime;
-# $order{paymentType} = $paymentType;
-# ++$session{changed};
-
-# # blank anything else
-# for my $column (@columns) {
-# defined $order{$column} or $order{$column} = '';
-# }
-# # make sure the user can't set these behind our backs
-# $order{filled} = 0;
-# $order{paidFor} = 0;
-
-# my $user = get_siteuser(\%session, $cfg, $CGI::Q);
-# if ($user) {
-# $order{userId} = $user->{userId};
-# $order{siteuser_id} = $user->{id};
-# }
-# else {
-# $order{userId} = '';
-# $order{siteuser_id} = -1;
-# }
-
-# # this should be hard to guess
-# $order{randomId} = md5_hex(time().rand().{}.$$);
-
-# # check if a customizer has anything to do
-# # if it sets shipping cost it must also update the total
-# eval {
-# my %custom = %{$session{custom}};
-# $cust_class->order_save($CGI::Q, \%order, \@cart, \@products,
-# \%custom, $cfg);
-# $session{custom} = \%custom;
-# };
-# if ($@) {
-# return checkout($@, 1);
-# }
-
-# $order{total} += $cust_class->total_extras(\@cart, \@products,
-# $session{custom}, $cfg, 'final');
-
-# my %subscribing_to;
-
-# # load up the database
-# my @data = @order{@columns};
-# shift @data; # lose the dummy id
-# my $order = BSE::TB::Orders->add(@data)
-# or die "Cannot add order";
-# my @items;
-# my @item_cols = BSE::TB::OrderItem->columns;
-# my @prod_xfer = qw/title summary subscription_id subscription_period/;
-# for my $row_num (0..$#cart) {
-# my $row = $cart[$row_num];
-# my $product = $products[$row_num];
-# $row->{orderId} = $order->{id};
-
-# # store product data too
-# @$row{@prod_xfer} = @{$product}{@prod_xfer};
-
-# # store the lapsed value, this prevents future changes causing
-# # variation of the expiry date
-# $row->{max_lapsed} = 0;
-# if ($product->{subscription_id} != -1) {
-# my $sub = $product->subscription;
-# $row->{max_lapsed} = $sub->{max_lapsed} if $sub;
-# }
-
-# my @data = @$row{@item_cols};
-
-# shift @data;
-# push(@items, BSE::TB::OrderItems->add(@data));
-
-# my $sub = $product->subscription;
-# if ($sub) {
-# $subscribing_to{$sub->{text_id}} = $sub;
-# }
-# }
-
-# if ($user) {
-# $user->recalculate_subscriptions($cfg);
-# }
-
-# my $item_index = -1;
-# my @options;
-# my $option_index;
-# my %acts;
-# %acts =
-# (
-# $cust_class->purchase_actions(\%acts, \@items, \@products,
-# $session{custom}, $cfg),
-# BSE::Util::Tags->static(\%acts, $cfg),
-# iterate_items_reset => sub { $item_index = -1; },
-# iterate_items =>
-# sub {
-# if (++$item_index < @items) {
-# $option_index = -1;
-# @options = cart_item_opts($items[$item_index],
-# $products[$item_index]);
-# return 1;
-# }
-# return 0;
-# },
-# item=> sub { CGI::escapeHTML($items[$item_index]{$_[0]}); },
-# product =>
-# sub {
-# my $value = $products[$item_index]{$_[0]};
-# defined $value or $value = '';
-
-# escape_html($value);
-# },
-# extended =>
-# sub {
-# my $what = $_[0] || 'retailPrice';
-# $items[$item_index]{units} * $items[$item_index]{$what};
-# },
-# order => sub { CGI::escapeHTML($order->{$_[0]}) },
-# money =>
-# sub {
-# my ($func, $args) = split ' ', $_[0], 2;
-# $acts{$func} || return "<: money $_[0] :>";
-# return sprintf("%.02f", $acts{$func}->($args)/100);
-# },
-# _format =>
-# sub {
-# my ($value, $fmt) = @_;
-# if ($fmt =~ /^m(\d+)/) {
-# return sprintf("%$1s", sprintf("%.2f", $value/100));
-# }
-# elsif ($fmt =~ /%/) {
-# return sprintf($fmt, $value);
-# }
-# },
-# iterate_options_reset => sub { $option_index = -1 },
-# iterate_options => sub { ++$option_index < @options },
-# option => sub { CGI::escapeHTML($options[$option_index]{$_[0]}) },
-# ifOptions => sub { @options },
-# options => sub { nice_options(@options) },
-# ifPayment => [ \&tag_ifPayment, $order->{paymentType}, \%types_by_name ],
-# #ifSubscribingTo => [ \&tag_ifSubscribingTo, \%subscribing_to ],
-# );
-# for my $type (@pay_types) {
-# my $id = $type->{id};
-# my $name = $type->{name};
-# $acts{"if${name}Payment"} = $order->{paymentType} == $id;
-# }
-# send_order($order, \@items, \@products, $noencrypt, \%subscribing_to);
-# $session{cart} = []; # empty the cart
-# page('checkoutfinal.tmpl', \%acts);
-# }
-
-# sub tag_ifSubscribingTo {
-# my ($subscribing_to, $args) = @_;
-
-# exists $subscribing_to->{$args};
-# }
-
-# sub tag_with_wrap {
-# my ($args, $text) = @_;
-
-# my $margin = $args =~ /^\d+$/ && $args > 30 ? $args : 70;
-
-# require Text::Wrap;
-# # do it twice to prevent a warning
-# $Text::Wrap::columns = $margin;
-# $Text::Wrap::columns = $margin;
-
-# return Text::Wrap::fill('', '', split /\n/, $text);
-# }
-
-# # sends the email order confirmation and the PGP encrypted
-# # email to the site owner
-# sub send_order {
-# my ($order, $items, $products, $noencrypt, $subscribing_to) = @_;
-
-# my %extras = $cfg->entriesCS('extra tags');
-# for my $key (keys %extras) {
-# # follow any links
-# my $data = $cfg->entryVar('extra tags', $key);
-# $extras{$key} = sub { $data };
-# }
-
-# my $item_index = -1;
-# my @options;
-# my $option_index;
-# my %acts;
-# %acts =
-# (
-# %extras,
-# custom_class($cfg)
-# ->order_mail_actions(\%acts, $order, $items, $products,
-# $session{custom}, $cfg),
-# BSE::Util::Tags->static(\%acts, $cfg),
-# iterate_items_reset => sub { $item_index = -1; },
-# iterate_items =>
-# sub {
-# if (++$item_index < @$items) {
-# $option_index = -1;
-# @options = cart_item_opts($items->[$item_index],
-# $products->[$item_index]);
-# return 1;
-# }
-# return 0;
-# },
-# item=> sub { $items->[$item_index]{$_[0]}; },
-# product =>
-# sub {
-# my $value = $products->[$item_index]{$_[0]};
-# defined($value) or $value = '';
-# $value;
-# },
-# order => sub { $order->{$_[0]} },
-# extended =>
-# sub {
-# $items->[$item_index]{units} * $items->[$item_index]{$_[0]};
-# },
-# _format =>
-# sub {
-# my ($value, $fmt) = @_;
-# if ($fmt =~ /^m(\d+)/) {
-# return sprintf("%$1s", sprintf("%.2f", $value/100));
-# }
-# elsif ($fmt =~ /%/) {
-# return sprintf($fmt, $value);
-# }
-# elsif ($fmt =~ /^\d+$/) {
-# return substr($value . (" " x $fmt), 0, $fmt);
-# }
-# else {
-# return $value;
-# }
-# },
-# iterate_options_reset => sub { $option_index = -1 },
-# iterate_options => sub { ++$option_index < @options },
-# option => sub { CGI::escapeHTML($options[$option_index]{$_[0]}) },
-# ifOptions => sub { @options },
-# options => sub { nice_options(@options) },
-# with_wrap => \&tag_with_wrap,
-# ifSubscribingTo => [ \&tag_ifSubscribingTo, $subscribing_to ],
-# );
-
-# my $mailer = BSE::Mail->new(cfg=>$cfg);
-# # ok, send some email
-# my $confirm = BSE::Template->get_page('mailconfirm', $cfg, \%acts);
-# my $email_order = $cfg->entryBool('shop', 'email_order', $SHOP_EMAIL_ORDER);
-# if ($email_order) {
-# unless ($noencrypt) {
-# $acts{cardNumber} = sub { param('cardNumber') };
-# $acts{cardExpiry} = sub { param('cardExpiry') };
-# }
-# my $ordertext = BSE::Template->get_page('mailorder', $cfg, \%acts);
-
-# my $send_text;
-# if ($noencrypt) {
-# $send_text = $ordertext;
-# }
-# else {
-# eval "use $crypto_class";
-# !$@ or die $@;
-# my $encrypter = $crypto_class->new;
-
-# my $debug = $cfg->entryBool('debug', 'mail_encryption', 0);
-# my $sign = $cfg->entryBool('basic', 'sign', 1);
-
-# # encrypt and sign
-# my %opts =
-# (
-# sign=> $sign,
-# passphrase=> $passphrase,
-# stripwarn=>1,
-# debug=>$debug,
-# );
-
-# $opts{secretkeyid} = $signing_id if $signing_id;
-# $opts{pgp} = $pgp if $pgp;
-# $opts{gpg} = $gpg if $gpg;
-# $opts{pgpe} = $pgpe if $pgpe;
-# my $recip = "$toName $toEmail";
-
-# $send_text = $encrypter->encrypt($recip, $ordertext, %opts )
-# or die "Cannot encrypt ", $encrypter->error;
-# }
-# $mailer->send(to=>$toEmail, from=>$from, subject=>'New Order '.$order->{id},
-# body=>$send_text)
-# or print STDERR "Error sending order to admin: ",$mailer->errstr,"\n";
-# }
-# $mailer->send(to=>$order->{emailAddress}, from=>$from,
-# subject=>$subject . " " . localtime,
-# body=>$confirm)
-# or print STDERR "Error sending order to customer: ",$mailer->errstr,"\n";
-# }
-
-# sub page {
-# my ($template, $acts) = @_;
-
-# BSE::Template->show_page($template, $cfg, $acts);
-# }
-
-# # convert an epoch time to sql format
-# sub epoch_to_sql {
-# use POSIX 'strftime';
-# my ($time) = @_;
-
-# return strftime('%Y-%m-%d', localtime $time);
-# }
-
-# sub refresh_logon {
-# my ($msg, $msgid, $r) = @_;
-# my $url = $securlbase."/cgi-bin/user.pl";
-
-# $r ||= $securlbase."/cgi-bin/shop.pl?checkout=1";
-
-# my %parms;
-# $parms{r} = $r;
-# $parms{message} = $msg if $msg;
-# $parms{mid} = $msgid if $msgid;
-# $url .= "?" . join("&", map "$_=".CGI::escape($parms{$_}), keys %parms);
-
-# refresh_to($url);
-# }
-
__END__
=head1 NAME
=head1 CHANGES
+=head2 0.15_15
+
+=over
+
+=item *
+
+seminars can now be added to orders (if the user is logged on and
+isn't already booked)
+
+=item *
+
+added a_location target to shop.pl to display location information to
+end-users (intended for use as a pop-up)
+
+=item *
+
+removed old commented code from shop.pl
+
+=item *
+
+subs.pl now has normal admin tags on the newsletter list, including
+correcting the help tag.
+
+=item *
+
+the validation of the article parent id was incorrect, causing
+problems when saving existing articles. Corrected the validation.
+
+=item *
+
+parsing and handling of the default value for the release and expire
+fields were reversed.
+
+=item *
+
+seminar display templates are now under the seminars directory
+
+=item *
+
+seminar display templates now have access to locations, location
+sessions and sessions iterators.
+
+=item *
+
+cart, checkoutnew and checkoutfinal templates now have access to
+per-item session and location tags
+
+=item *
+
+you can now add a user as a seminar attendee, without them having made
+an order.
+
+=item *
+
+DevHelp::Date had been changed to try to import its import method from
+Exporter, but this doesn't work on older perls. Reverted to subclass
+Exporter.
+
+=back
+
This is a development release, not intended for production.
=head2 0.15_14
--- /dev/null
+<:wrap admin/xbase.tmpl title=>"Add Seminar Attendee":>
+<h1>Add Seminar Attendee - Select a Seminar</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:>
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a>
+| <a href="<:script:>?id=<:siteuser id:>">Edit user</a> |
+</p>
+<p>Adding user <:siteuser userId:> as an attendee to:</p>
+<!-- leave this as get, since submitting it just displays a new page -->
+<form action="<:script:>" method="get" name="addattendee1">
+<input type="hidden" name="siteuser_id" value="<:siteuser id:>" />
+<:ifCgi r:><input type="hidden" name="r" value="<:cgi r:>" /><:or:><:eif:>
+<table>
+ <tr>
+ <th>Seminar:</th>
+ <td><select name="seminar_id">
+<option value="">(select a seminar)</option>
+<:iterator begin seminars:>
+<option value="<:seminar id:>" <:ifEq [old seminar_id] [seminar id]:>selected="selected"<:or:><:eif:>><:seminar title:> (<:seminar id:>)</option>
+<:iterator end seminars:>
+ </select></td>
+ <td><:error_img seminar_id:></td>
+ </tr>
+ <tr>
+ <td colspan="3"><input type="submit" name="a_addattendsession" value="Select Session >>" /></td>
+ </tr>
+</table>
--- /dev/null
+<:wrap admin/xbase.tmpl title=>"Add Seminar Attendee":>
+<h1>Add Seminar Attendee - Select a Session</h1>
+<:ifMessage:>
+<p><b><:message:></b></p>
+<:or:><:eif:>
+<p>| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> |
+<a href="<:script:>?id=<:siteuser id:>">Edit user</a> |
+</p>
+<p>Adding user <:siteuser userId:> as an attendee to:</p>
+<!-- leave this as get, since submitting it just displays a new page -->
+<form action="<:script:>" method="get" name="addattendee1">
+<input type="hidden" name="siteuser_id" value="<:siteuser id:>" />
+<input type="hidden" name="seminar_id" value="<:seminar id:>" />
+<:ifCgi r:><input type="hidden" name="r" value="<:cgi r:>" /><:or:><:eif:>
+<table>
+ <tr>
+ <th>Seminar:</th>
+ <td><:seminar title:></td>
+ </tr>
+ <tr>
+ <th>Session:</th>
+ <td><select name="session_id">
+<option value="">(select a session)</option>
+<:iterator begin sessions:>
+<option value="<:session id:>" <:ifEq [old session_id] [session id]:>selected="selected"<:or:><:eif:>><:session description:> <:date "%H:%M %d/%m/%Y" session when_at:></option>
+<:iterator end sessions:>
+ </select></td>
+ <td><:error_img session_id:></td>
+ </tr>
+ <tr>
+ <td colspan="3"><input type="submit" name="a_addattendsave" value="Select Session >>" /></td>
+ </tr>
+</table>
| <a href="/cgi-bin/admin/menu.pl">Admin menu</a> |
<a href="/cgi-bin/admin/siteusers.pl">Site Members</a> |
<a href="mailto:<:siteuser email:>">Email</a>
-<:ifUserorders:>| <a href="/cgi-bin/admin/siteusers.pl?a_edit=1&id=<:siteuser id:>&_t=orders">Orders</a><:or:><:eif:> |</p>
+<:ifUserorders:>| <a href="/cgi-bin/admin/siteusers.pl?a_edit=1&id=<:siteuser id:>&_t=orders">Orders</a><:or:><:eif:> |
+<a href="/cgi-bin/admin/admin_seminar.pl?a_addattendseminar=1&siteuser_id=<:siteuser id:>">Add to seminar</a> |
+</p>
<:ifMessage:>
<p><b><:message:></b></p>
<td width="100%" align="left"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><a href="<:item link:>"><:item
summary:> <:if Options:>(<:iterator begin options:><:option desc:>:
<:option label:><:iterator separator options:>, <:iterator end options:>)<:or
- Options:><:eif Options:></a></font></td>
+ Options:><:eif Options:></a><:ifItem session_id:>(session at <:location description:> <:date "%H:%M %d/%m/%Y" session when_at:>)<:or:><:eif:></font></td>
<td nowrap align="center">
<input type="text" name="quantity_<:index:>" size="2" value="<:item units:>">
</td>
</tr>
<:iterator begin items:>
<tr valign="middle" align="center" bgcolor="#FFFFFF">
- <td width="100%" align="left"> <a href="<:product link:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:product
- summary:> <:options:></font></a></td>
+ <td width="100%" align="left"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><a href="<:product link:>"><:product
+ summary:></a> <:options:><:ifItem session_id:>(session at <:location description:> <:date "%H:%M %d/%m/%Y" session when_at:>)<:or:><:eif:></font></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>$<:
</tr>
<:iterator begin items:>
<tr valign="middle" align="center" bgcolor="#FFFFFF">
- <td width="100%" align="left"> <a href="<:item link:>"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:item
- summary:> <:options:></font></a></td>
+ <td width="100%" align="left"> <font face="Verdana, Arial, Helvetica, sans-serif" size="-2"><a href="<:item link:>"><:item
+ summary:> <:options:></a><:ifItem session_id:>(session at <:location description:> <:date "%H:%M %d/%m/%Y" session when_at:>)<:or:><:eif:></font></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>$<:
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>Location: <:location description:></title>
+ <link rel="stylesheet" href="/css/admin.css">
+ </head>
+<body>
+<h1><:location description:></h1>
+<table>
+<tr><th>Address:</th>
+<td>
+<:ifLocation room:><:location room:><br /><:or:><:eif:>
+<:location street1:><br />
+<:ifLocation street2:><:location street2:><br /><:or:><:eif:>
+<:location suburb:> <:location state:> <:location postcode:>
+<:ifLocation country:><br /><:location country:><:or:><:eif:>
+</td></tr>
+<:if Location public_notes:>
+<tr>
+ <th>Notes</th>
+ <td><:bodytext location public_notes:></td>
+</tr>
+<:or Location:><:eif Location:>
+</table>
+</body></html>
\ No newline at end of file
--- /dev/null
+ <:wrap base.tmpl:> <:embed start:><:admin:>
+<script>
+function show_location(locationid) {
+ window.open('/cgi-bin/shop.pl?a_location=1&location_id='+locationid,
+ 'location',
+ 'width=600,height=300,location=no,status=no,menubar=no,scrollbars=yes');
+ return false;
+}
+</script>
+<table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td width="80%" height="24"> <font face="Arial, Helvetica, sans-serif" size="4" color="#FF7F00"><b><:seminar
+ title:></b></font></td>
+ <td height="24"> </td>
+ </tr>
+ <tr>
+ <td bgcolor="#999999" colspan="2" height="1"><img src="/images/trans_pixel.gif" width="24" height="1" border="0"></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <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>
+ / <:iterator begin crumbs:> <a href="<:url crumbs:>"><font color="#FFFFFF"><:crumbs
+ title:></font></a> / <:iterator end crumbs:></font></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<p><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:body:></font></p>
+<:if StepCats:> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">
+<p><b>Related categories:</b></p>
+<ul>
+<:iterator begin stepcats:>
+<li><a href="<:url stepcat:>"><:stepcat title:></a></li>
+<:iterator end stepcats:>
+</ul></font>
+<:or StepCats:><:eif StepCats:>
+<:if Product retailPrice:>
+<form name="ff" method="POST" action="/cgi-bin/shop.pl">
+<p><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Select a seminar session to attend:</font></p>
+ <:if Cfg seminar locations:>
+ <:iterator begin locations:>
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b><a href="/cgi-bin/shop.pl?a_location=1&location_id=<:location id:>" onClick="return show_location(<:location id:>)"><:location description:></a></b></font></p>
+ <ul>
+ <:iterator begin location_sessions:>
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><input type="radio" name="session_id" value="<:location_session id:>" /><:date "%H:%M %d/%m/%Y" location_session when_at:></font></p>
+ <:iterator end location_sessions:>
+ </ul>
+ <:iterator end locations:>
+ <:or Cfg:>
+ <:iterator begin sessions:>
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><input type="radio" name="session_id" value="<:session id:>" /><a href="/cgi-bin/shop.pl?a_location=1&location_id=<:session location_id:>" onClick="return show_location(<:session location_id:>)"><:session description:></a> <:date "%H:%M %d/%m/%Y" session when_at:></font></p>
+ <:iterator end sessions:>
+ <:eif Cfg:>
+<:if Options:>
+ <table>
+<tr>
+ <:iterator begin options:><td valign="middle"> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"><b><:option desc:>:</b></font></td><td> <:option popup:> </td><:iterator end options:>
+</tr>
+</table>
+ <:or Options:><:eif Options:>
+ <:ifProduct leadTime:>
+
+ <p><b><font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="#FE7F00">Usually ships in:</font><font face="Verdana, Arial, Helvetica, sans-serif" size="-2"> <:seminar leadTime:> <:if Eq [product leadTime] "1":>day<:or Eq:>days<:eif Eq:></font></b>
+</p>
+ <:or:><br><:eif:>
+
+<table border="0" cellspacing="0" cellpadding="0">
+ <tr valign="middle" align="center">
+ <td bgcolor="#666666">
+ <table width="100%" border="0" cellspacing="1" cellpadding="4" height="30">
+ <tr valign="middle" align="center">
+ <td bgcolor="#666666" align="left"> <font size="2" face="Verdana, Arial, Helvetica, sans-serif" color="#FFFFFF">
+ <b>Price:</b></font> </td>
+ <td bgcolor="#FFFFFF"> <font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#000000">
+ <b>$<:money product retailPrice:> </b>(inc GST)</font> </td>
+ </tr>
+ </table>
+ </td>
+ <td nowrap>
+ <input type="hidden" name="id" value="<:seminar id:>">
+ <input type="hidden" name="quantity" value="1">
+ <input type="submit" name="add" value="Add to cart">
+ <input type="submit" name="cart" value="View cart">
+ </td>
+ </tr>
+ </table>
+</form>
+<:or Product:><br>
+<br>
+<table border="0" cellspacing="0" cellpadding="1" bgcolor="#CCCCCC">
+ <tr>
+ <td>
+ <table width="100%" border="0" cellspacing="0" cellpadding="10" bgcolor="#FFFFFF">
+ <tr>
+ <td>
+ <form name="notifyme" method="post" action="/cgi-bin/interest.pl">
+ <font face="Arial, Helvetica, sans-serif" size="4"><b>Coming soon!</b></font>
+ <input type="hidden" name="product" value="<:seminar title:>">
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="-2">Yes,
+ I want this product, notify me when it becomes available</font></p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2">
+ Email:</font></b> </td>
+ <td>
+ <input type="text" name="email" size="32">
+ </td>
+ <td>
+ <input type="submit" name="Submit" value="Notify me!">
+ </td>
+ </tr>
+ </table>
+ </form>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<font face="Arial, Helvetica, sans-serif"><b><font size="4"> </font></b></font><:eif
+Product:>
+<p><br>
+ <a href="/shop/index.html"><img src="/images/store/browse_more.gif" width="133" height="21" border="0"></a>
+</p><br>
+<:if Files:>
+<table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td>
+ <table border="0" cellspacing="0" cellpadding="4" bgcolor="#999999">
+ <tr>
+ <th nowrap><font face="Verdana, Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"> Related
+ file downloads </font></th>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td bgcolor="#999999">
+ <table cellspacing="1" cellpadding="4">
+ <tr bgcolor="#CCCCCC">
+ <th><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif">Description</font></th>
+ <th><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif">Filename</font></th>
+ <th><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif">Size</font></th>
+ <th><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif">Status</font></th>
+ </tr>
+ <:iterator begin files:>
+ <tr bgcolor="#FFFFFF">
+ <td bgcolor="#FFFFFF"><font font color="#000000" face="Verdana, Arial, Helvetica, sans-serif" size="-2"><:file
+ description:></font></td>
+ <td bgcolor="#FFFFFF"><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif"><:if
+ File forSale:><:file displayName:><:or File:><a href="/cgi-bin/user.pl?download_file=1&file=<:file id:><:ifFile requireUser:>&r=<:url article:><:or:><:eif:>">
+ <:file displayName:></a><:eif File:></font></td>
+ <td align="right"><font color="#000000" size="-2" face="Verdana, Arial, Helvetica, sans-serif"><:kb
+ file sizeInBytes:></font></td>
+ <td nowrap align="center"> <:if File forSale:><img src="/images/filestatus/locked.gif" width="15" height="15" alt="Locked" title="Locked"><img src="/images/filestatus/forSale.gif" width="15" height="15" alt="File must be purchased" title="File must be purchased"><:or
+ File:><a href="/cgi-bin/user.pl?download_file=1&file=<:file id:><:ifFile requireUser:>&r=<:url article:><:or:><:eif:>"><img src="/images/filestatus/download.gif" width="15" height="15" alt="Download now" title="Download now" border="0"></a><:ifFile
+ requireUser:><img src="/images/filestatus/requireUser.gif" width="15" height="15" alt="For registered users only" title="For registered users only"><:or:><img src="/images/trans_pixel.gif" width="15" height="15" title="For registered users only"><:eif:><:eif
+ File:></td>
+ </tr>
+ <:iterator end files:> </table>
+ </td>
+ </tr>
+</table>
+<:or Files:><:eif Files:><:embed end:>
\ No newline at end of file
EOS
my $entered = <STDIN>;
chomp $entered;
- if ($conf ne $conf) {
+ if ($entered ne $conf) {
print "Either you didn't backup your data of you didn't read the message.\n";
exit;
}
for my $i (0..$#ccols) {
my $col = $cols->[$i];
my $ccol = $ccols[$i];
+ if ($ccol->{type} =~ /^varchar\((\d+)\) binary$/) {
+ $ccol->{type} = "varbinary($1)";
+ }
defined $ccol->{default} or $ccol->{default} = 'NULL';
$col->{field} eq $ccol->{field}
if ($col->{type} ne $ccol->{type} || $col->{default} ne $ccol->{default}) {
print "fixing type or default for $col->{field}\n" if $verbose;
+ if ($verbose > 1) {
+ print "old type: $ccol->{type} new type: $col->{type}\n"
+ if $ccol->{type} ne $col->{type};
+ print "old default: $ccol->{default} new default: $col->{default}\n"
+ if $ccol->{default} ne $col->{default};
+ }
my $sql = "alter table $table modify ".create_clauses($col);
run_sql($sql)
or die "Cannot fix $col->{field} type/default: $DBI::errstr\n";
#inpho.test_password=test
bse location validation.postcode_description=Funky Postcode
+
+seminar.locations=1