-VERSION=0.15_53
+VERSION=0.15_54
DISTNAME=bse-$(VERSION)
DISTBUILD=$(DISTNAME)
DISTTAR=../$(DISTNAME).tar
-- position of first image for this article
imagePos char(2) not null,
- release datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
- expire datetime DEFAULT '9999-12-31 23:59:59' NOT NULL,
+ `release` datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
+ expire datetime DEFAULT '2999-12-31 23:59:59' NOT NULL,
keyword varchar(255) not null default '',
-- the template in $TMPLDIR used to generate this as HTML
metaDescription varchar(255) default '' not null,
metaKeywords varchar(255) default '' not null,
+ -- x just so we don't get a name issue with product
+ summaryx varchar(255) default '' not null,
+
PRIMARY KEY (id),
-- if we keep id in the indexes MySQL will sometimes be able to
-- Unfortunately MySQL can only do this on fixed-width columns
-- other databases may not need the id in the index, and may also be
-- able to handle the variable length columns in the index
- INDEX article_date_index (release,expire, id),
+ INDEX article_date_index (`release`,expire, id),
INDEX article_displayOrder_index (displayOrder),
INDEX article_parentId_index (parentId),
INDEX article_level_index (level, id)
subscription_period integer not null default 0,
subscription_usage integer not null default 3,
subscription_required integer not null default -1,
+
+ product_code varchar(80) not null,
primary key(articleId)
);
delivStreet2 varchar(127) not null default '',
billStreet2 varchar(127) not null default '',
+ purchase_order varchar(80) not null default '',
+
primary key (id),
index order_cchash(ccNumberHash),
index order_userId(userId, orderDate)
-- session for a seminar
session_id integer not null default -1,
+ product_code varchar(80) not null default '',
+
primary key (id),
index order_item_order(orderId, id)
);
-- order as seen from the child
childDisplayOrder integer not null,
- release datetime default '0000-00-00 00:00:00' not null,
+ `release` datetime default '0000-00-00 00:00:00' not null,
expire datetime default '9999-12-31 23:59:59' not null,
primary key(id),
file_displayName => 2,
file_description=>2,
file_notes => 1,
+ summary => 0,
+ description => 0,
+ product_code => 0,
);
for my $name (keys %scores) {
next unless $gen->visible($article) or $do_search{$sectionid};
next if $dont_search{$sectionid};
+
+ $article = $gen->get_real_article($article);
my %fields;
for my $field (sort { $scores{$b} <=> $scores{$a} } keys %scores) {
customInt1 customInt2 customInt3 customInt4
lastModifiedBy created createdBy author pageTitle
force_dynamic cached_dynamic inherit_siteuser_rights
- metaDescription metaKeywords/;
+ metaDescription metaKeywords summary/;
}
sub numeric {
(
Articles => 'select * from article',
replaceArticle =>
- 'replace article values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ 'replace article values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
addArticle =>
- 'insert article values (null, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ 'insert article values (null, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
deleteArticle => 'delete from article where id = ?',
getArticleByPkey => 'select * from article where id = ?',
searchIndexWC => 'select * from searchindex where id like ?',
Products=> 'select article.*, product.* from article, product where id = articleId',
- addProduct => 'insert product values(?,?,?,?,?,?,?,?,?,?,?)',
+ addProduct => 'insert product values(?,?,?,?,?,?,?,?,?,?,?,?)',
getProductByPkey => 'select article.*, product.* from article, product where id=? and articleId = id',
- replaceProduct => 'replace product values(?,?,?,?,?,?,?,?,?,?,?)',
+ replaceProduct => 'replace product values(?,?,?,?,?,?,?,?,?,?,?,?)',
'Products.stepProducts' => <<EOS,
select ar.*, pr.* from article ar, product pr, other_parents op
where ar.id = pr.articleId and op.childId = ar.id and op.parentId = ?
Orders => 'select * from orders',
getOrderByPkey => 'select * from orders where id = ?',
getOrderItemByOrderId => 'select * from order_item where orderId = ?',
- addOrder => 'insert orders values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
- replaceOrder => 'replace orders values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
- addOrderItem => 'insert order_item values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ addOrder => 'insert orders values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ replaceOrder => 'replace orders values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ addOrderItem => 'insert order_item values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
getOrderByUserId => 'select * from orders where userId = ?',
deleteOrdersItems => 'delete from order_item where orderId = ?',
my $dbh = DBI->connect_cached( $DSN, $UN, $PW)
or die "Cannot connect to database: $DBI::errstr";
+ # this might fail, but I don't care
+ $dbh->do("set session sql_mode='ansi_quotes'");
+
$self = bless { dbh => $dbh }, $class;
}
$self;
use BSE::Util::Iterate;
use BSE::Template;
+sub not_logged_on {
+ my ($self, $req) = @_;
+
+ if (() = $req->cgi->param('_')) {
+ # this check doesn't seem to work on IE:
+ # $ENV{HTTP_X_REQUESTED_WITH} =~ /XMLHttpRequest/) {
+ # AJAX/Prototype request
+ return
+ {
+ content => 'Access Forbidden: login timed out',
+ headers => [
+ "Status: 403", # forbidden
+ ],
+ };
+ }
+ else {
+ BSE::Template->get_refresh($req->url('logon'), $req->cfg);
+ }
+}
+
sub article_dispatch {
my ($self, $req, $article, $articles) = @_;
BSE::Permissions->check_logon($req)
- or return BSE::Template->get_refresh($req->url('logon'), $req->cfg);
+ or return $self->not_logged_on($self);
my $cgi = $req->cgi;
my $action;
hide => 'hide',
unhide => 'unhide',
a_thumb => 'req_thumb',
+ a_ajax_get => 'req_ajax_get',
+ a_ajax_save_body => 'req_ajax_save_body',
+ a_ajax_set => 'req_ajax_set',
);
}
1; # no extra validation
}
+sub req_ajax_get {
+ my ($self, $req, $article, $articles, @extras) = @_;
+
+ my $field_name = $req->cgi->param('field');
+ unless ($field_name && exists $article->{$field_name}) {
+ print STDERR "req_ajax_get: missing or invalid field parameter\n";
+ return {
+ contant => 'Invalid or missing field name',
+ headers => [
+ "Status: 187" # bad request
+ ],
+ };
+ }
+
+ my $value = $article->{$field_name};
+ defined $value or $value = '';
+
+ my $charset = $req->cfg->entry('html', 'charset', 'iso-8859-1');
+
+ # re-encode to utf8
+ require Encode;
+ Encode::from_to($value, $charset, 'utf8');
+
+ # make some content
+ return
+ {
+ content => $value,
+ type => 'text/plain; charset=utf-8',
+ };
+}
+
+sub req_ajax_save_body {
+ my ($self, $req, $article, $articles, @extras) = @_;
+
+ my $cfg = $req->cfg;
+ my $cgi = $req->cgi;
+
+ $cgi->charset('utf-8');
+
+ # newer versions of CGI.pm will decode the content as UTF8 if we
+ # do the above
+ my $body = $cgi->param('body');
+
+ my $charset = $req->cfg->entry('html', 'charset', 'iso-8859-1');
+
+ # convert it to our working charset
+ # any characters that don't convert are replaced by some
+ # substitution character, not defined by the documentation
+ require Encode;
+ $body = Encode::encode($charset, $body);
+
+ $article->{body} = $body;
+ $article->{lastModified} = now_sqldatetime();
+ my $user = $req->getuser;
+ $article->{lastModifiedBy} = $user ? $user->{logon} : '';
+ $article->save;
+
+ my @extra_regen;
+ @extra_regen = $self->update_child_dynamic($article, $articles, $req);
+
+ if ($Constants::AUTO_GENERATE) {
+ require Util;
+ Util::generate_article($articles, $article);
+ for my $regen_id (@extra_regen) {
+ my $regen = $articles->getByPkey($regen_id);
+ Util::generate_low($articles, $regen, $self->{cfg});
+ }
+ }
+
+ # we need the formatted body as the result
+ my $genname = $article->{generator};
+ eval "use $genname";
+ $@ and die "Error on use $genname: $@";
+ my $gen = $genname->new(article => $articles, cfg => $cfg, top => $article);
+ my %acts;
+ %acts = $gen->baseActs($articles, \%acts, $article, 0);
+ my $template = "<:body:>";
+ my $formatted = BSE::Template->replace($template, $req->cfg, \%acts);
+
+ return
+ {
+ content => $formatted,
+ type => BSE::Template->html_type($cfg),
+ };
+}
+
+my %settable_fields = qw(title keyword author pageTitle);
+
+
+sub req_ajax_set {
+ my ($self, $req, $article, $articles, @extras) = @_;
+
+ my $cfg = $req->cfg;
+ my $cgi = $req->cgi;
+
+ my $field = $cgi->param('field');
+
+ unless ($field && $settable_fields{$field}) {
+ return {
+ contant => 'Invalid or missing field name',
+ headers => [
+ "Status: 187" # bad request
+ ],
+ };
+ }
+
+ $cgi->charset('utf-8');
+
+ # newer versions of CGI.pm will decode the content as UTF8 if we
+ # do the above
+ my $value = $cgi->param('value');
+
+ # hack - validate it if it's the title
+ if ($field eq 'title') {
+ if ($value !~ /\S/) {
+ return {
+ contant => 'Invalid or missing field name',
+ headers => [
+ "Status: 187" # bad request
+ ],
+ };
+ }
+ }
+
+ my $charset = $req->cfg->entry('html', 'charset', 'iso-8859-1');
+
+ # convert it to our working charset
+ # any characters that don't convert are replaced by some
+ # substitution character, not defined by the documentation
+ require Encode;
+ $value = Encode::encode($charset, $value);
+
+ $article->{$field} = $value;
+ $article->{lastModified} = now_sqldatetime();
+ my $user = $req->getuser;
+ $article->{lastModifiedBy} = $user ? $user->{logon} : '';
+ $article->save;
+
+ my @extra_regen;
+ @extra_regen = $self->update_child_dynamic($article, $articles, $req);
+
+ if ($Constants::AUTO_GENERATE) {
+ require Util;
+ Util::generate_article($articles, $article);
+ for my $regen_id (@extra_regen) {
+ my $regen = $articles->getByPkey($regen_id);
+ Util::generate_low($articles, $regen, $self->{cfg});
+ }
+ }
+
+ return
+ {
+ content => $value,
+ type => BSE::Template->html_type($cfg),
+ };
+}
+
1;
=head1 NAME
or $src->{leadTime} = 0;
$data->{leadTime} = $src->{leadTime};
}
- if (exists $src->{summary} && length $src->{summary}) {
+ if (exists $src->{description} && length $src->{description}) {
if ($data->{id}) {
- if ($req->user_can('edit_field_edit_summary', $data)) {
- $data->{summary} = $src->{summary};
+ if ($req->user_can('edit_field_edit_description', $data)) {
+ $data->{description} = $src->{description};
+ }
+ }
+ }
+ if (exists $src->{product_code} && length $src->{product_code}) {
+ if ($data->{id}) {
+ if ($req->user_can('edit_field_edit_product_code', $data)) {
+ $data->{product_code} = $src->{product_code};
}
}
}
$seminar->future_location_sessions($$rlocation);
}
+sub get_real_article {
+ my ($self, $article) = @_;
+
+ return BSE::TB::Seminars->getByPkey($article->{id});
+}
+
1;
my @checks =
qw(
edit_delete_article
- edit_field_edit_title
- edit_field_edit_summary
edit_add_child
);
my %checks = map { $_=> $_, "bse_$_" => $_ } @checks;
return 1;
}
-sub check_edit_field_edit_title {
- my ($self, $user, $article, $action, $rmsg) = @_;
-
- if (_is_product_and_in_use($article)) {
- $$rmsg = "There are orders for this product. The title cannot be changed.";
- return;
- }
-
- return 1;
-}
-
-sub check_edit_field_edit_summary {
- my ($self, $user, $article, $action, $rmsg) = @_;
-
- if (_is_product_and_in_use($article)) {
- $$rmsg = "There are orders for this product. The summary cannot be changed.";
- return;
- }
-
- return 1;
-}
-
sub check_edit_add_child {
my ($self, $user, $article, $action, $rmsg) = @_;
SWITCH: for ($date) {
$_ eq 'ar' # been released
&& do {
- $sql .= " and $now between release and expire";
+ $sql .= " and $now between \"release\" and expire";
last SWITCH;
};
/^r(\d+)$/ # released in last N days
&& do {
- $sql .= " and release > "._sql_date(time - $oneday * $1);
+ $sql .= " and \"release\" > "._sql_date(time - $oneday * $1);
last SWITCH;
};
/^e(\d+)$/ # expired in last N days
delivMobile billMobile
ccOnline ccSuccess ccReceipt ccStatus ccStatusText
ccStatus2 ccTranId complete delivOrganization billOrganization
- delivStreet2 billStreet2/;
+ delivStreet2 billStreet2 purchase_order/;
}
=item siteuser
billMobile => { description => 'Billing Mobile Number',
rules=>'phone' },
instructions => { description => 'Instructions' },
+ purchase_order => { description => 'Purchase Order No' },
);
for my $field (keys %fields) {
return qw/id productId orderId units price wholesalePrice gst options
customInt1 customInt2 customInt3 customStr1 customStr2 customStr3
title summary subscription_id subscription_period max_lapsed
- session_id/;
+ session_id product_code/;
}
1;
push @{$result->{headers}}, "Content-Type: $result->{type}"
if $result->{type};
push @{$result->{headers}}, $req->extra_headers;
+ my $add_cache_control = 1;
+ for my $header (@{$result->{headers}}) {
+ if ($header =~ /^cache-control:/i) {
+ $add_cache_control = 0;
+ last;
+ }
+ }
+ if ($add_cache_control) {
+ push @{$result->{headers}}, "Cache-Control: no-cache";
+ }
if (exists $ENV{GATEWAY_INTERFACE}
&& $ENV{GATEWAY_INTERFACE} =~ /^CGI-Perl\//) {
require Apache;
my $cust_class = custom_class($req->cfg);
eval {
+ local $SIG{__DIE__};
my %custom = %{$session->{custom}};
$cust_class->order_save($cgi, $order_values, \@items, \@products,
\%custom, $cfg);
#ifSubscribingTo => [ \&tag_ifSubscribingTo, \%subscribing_to ],
session => [ \&tag_session, \$item, \$sem_session ],
location => [ \&tag_location, \$item, \$location ],
+ msg => '',
);
for my $type (@pay_types) {
my $id = $type->{id};
# if it sets shipping cost it must also update the total
eval {
+ local $SIG{__DIE__};
my %custom = %{$session->{custom}};
$cust_class->order_save($cgi, $values, $items, $items,
\%custom, $cfg);
sub static {
my ($class, $acts, $cfg) = @_;
+ my $static_ajax = $cfg->entry('basic', 'staticajax', 0);
require BSE::Util::Iterate;
my $it = BSE::Util::Iterate->new;
return
# report conflicts with a tag name used within reports
subreport => [ \&tag_report, $cfg ],
- ajax => '',
- ifAjax => 0,
+ (
+ $static_ajax
+ ? (
+ ajax => [ \&tag_ajax, $cfg ],
+ ifAjax => 1,
+ )
+ : (
+ ajax => '',
+ ifAjax => 0,
+ )
+ ),
_format =>
sub {
dynreplace => \&tag_replace,
dyntoday => \&tag_today,
dynreport => [ \&tag_report, $cfg ],
- ajax => [ \&tag_ajax, $cfg ],
+ ajax => [ \&tag_ajax_dynamic, $cfg ],
ifAjax => [ \&tag_ifAjax, $cfg ],
);
}
return _if_ajax($cfg) ? 1 : 0;
}
-sub tag_ajax {
+sub tag_ajax_dynamic {
my ($cfg, $args, $acts, $tag_name, $templater) = @_;
return '' unless _if_ajax($cfg);
-
+
+ return tag_ajax($cfg, $args, $acts, $tag_name, $templater);
+}
+
+sub tag_ajax {
+ my ($cfg, $args, $acts, $tag_name, $templater) = @_;
+
my ($name, $arg_rest) = split ' ', $args, 2;
my $defn = $cfg->entry('ajax definitions', $name)
(
(?:\s+
(?:
- [^\s\[\]]\S*
+ [^\s\[\]]+
+ |
+ \"[^"]*\"
|
\[[^\]\[]+?\]
)
}
}
+sub get_real_article {
+ my ($self, $article) = @_;
+
+ return $article;
+}
+
1;
__END__
return $article->{listed};
}
+sub get_real_article {
+ my ($self, $article) = @_;
+
+ return Products->getByPkey($article->{id});
+}
+
1;
__END__
sub columns {
return ($_[0]->SUPER::columns(),
- qw/articleId summary leadTime retailPrice wholesalePrice gst options
+ qw/articleId description leadTime retailPrice wholesalePrice gst options
subscription_id subscription_period subscription_usage
- subscription_required/ );
+ subscription_required product_code/ );
}
sub bases {
#!/usr/bin/perl -w
# -d:ptkdb
-BEGIN { $ENV{DISPLAY} = '192.168.32.15:0.0' }
+BEGIN { $ENV{DISPLAY} = '192.168.32.50:0.0' }
use strict;
use FindBin;
use lib "$FindBin::Bin/modules";
#!/usr/bin/perl -w
# -d:ptkdb
-BEGIN { $ENV{DISPLAY} = '192.168.32.15:0.0' }
+BEGIN { $ENV{DISPLAY} = '192.168.32.50:0.0' }
use strict;
use FindBin;
use lib "$FindBin::Bin/modules";
=head1 CHANGES
+=head2 0.15_54
+
+=over
+
+=item *
+
+orders now have a purchase_order field.
+
+=item *
+
+products now have a product_code field. This is transferred to order
+items when they are ordered.
+
+=item *
+
+added a summary field to articles. The old product summary field is
+now known as description, though the in database name of the column
+hasn't changed.
+
+=item *
+
+search indexing of the product_code, summary and description fields
+are controllable by the config file, as for the indexable article
+fields.
+
+=item *
+
+the ajax tags can be enabled for static pages
+
+=item *
+
+we now set ansi_quote mode when connecting to a mysql database, so we
+can use portal identifier quoting in queries.
+
+=item *
+
+the handling of column defaults has changed for upgrade_mysql.pl to
+deal with some mysql 5 issues. Be aware of this and backup your
+database before upgrading.
+
+=item *
+
+the product title and description (previously summary) fields are now
+editable on products that have been ordered previously
+
+=item *
+
+most dynamic output now has a "Cache-Control: no-cache" header, which
+should prevent caching by over-zealous UAs.
+
+=item *
+
+added new targets to cgi-bin/admin/add.pl to support ajax.
+
+=item *
+
+parsing of [] constructs in tags has changed to require spaces around
+subsidiary []. If you have strings containing [] characters as
+arguments you will need to add "" around them.
+
+=back
+
=head2 0.15_53
=over
If this is true, then pre-generation for dynamic pages will be delayed
until the page is displayed to a user. Default: off.
+=item staticajax
+
+If true, the ifAjax and ajax tags will be active for static pages.
+
=back
=head2 [mail]
The default scores are:
- Field Score
- ----- -----
- title 5
- body 3
- keyword 4
-
-A special key C<file_description> can be used here to set the score
-for indexing downloadable file descriptions, which aren't indexed by
-default. A good value is probably 2 or 1.
+ Field Score Notes
+ ----- ----- -----
+ title 5
+ body 3
+ keyword 4
+ pageTitle 5
+ author 4
+ summary 0
+ description 0 Products only
+ product_code 0 Products only
+ file_displayName 2 displayName for files
+ file_description 2 description for files
+ file_notes 1 notes for files
=head2 [article flags]
<div>
<h2><a name="title"></a>Title</h2>
- <p>The name of the product (NB: the title
-cannot be changed once an order has
- been placed that includes
-this product). (The ‘title’ is indexed by the built-in search engine).</p>
+ <p>The name of the product. (The ‘title’ is indexed by the built-in search engine).</p>
</div>
<div>
<h2><a name="summary"></a>Summary</h2>
- <p>The extended name of the product
-(NB: the summary cannot be changed once
- an order has been placed
-that includes this product).</p>
+ <p>The extended name of the product.</p>
</div>
<td>
<table border=0 cellspacing="1" cellpadding="6">
<tr>
- <th nowrap align="left" bgcolor="#FFFFFF">Title*:</th>
+ <th nowrap align="left" bgcolor="#FFFFFF">Title:</th>
<td nowrap bgcolor="#FFFFFF">
<input type="text" name="title" value="<:old title:>" size=60><:error_img title:>
</td>
<td nowrap bgcolor="#FFFFFF"><:help product title:></td>
</tr>
<tr>
- <th nowrap align="left" bgcolor="#FFFFFF">Summary*:</th>
+ <th nowrap align="left" bgcolor="#FFFFFF">Summary:</th>
<td nowrap bgcolor="#FFFFFF">
<input type="text" name="summary" value="<:old summary:>" size=60><:error_img summary:>
</td>
<td nowrap bgcolor="#FFFFFF"><:help product summary:></td>
</tr>
+ <tr>
+ <th nowrap align="left" bgcolor="#FFFFFF">Description:</th>
+ <td nowrap bgcolor="#FFFFFF">
+ <input type="text" name="description" value="<:old description:>" size=60><:error_img description:>
+ </td>
+ <td nowrap bgcolor="#FFFFFF"><:help product description:></td>
+ </tr>
+ <tr>
+ <th nowrap align="left" bgcolor="#FFFFFF">Product Code:</th>
+ <td nowrap bgcolor="#FFFFFF">
+ <input type="text" name="product_code" value="<:old product_code:>" size="40"><:error_img product_code:>
+ </td>
+ <td nowrap bgcolor="#FFFFFF"><:help product product_code:></td>
+ </tr>
<tr>
<th nowrap align="left" bgcolor="#FFFFFF">Catalog:</th>
<td nowrap bgcolor="#FFFFFF"> <select name="parentid"><:list:></select><:error_img parentid:> </td>
<:or:><:default title:><:eif:></td>
<td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit title:> <:error_img title:></td>
</tr>
+ <tr>
+ <th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Summary:
+ </th>
+ <td bgcolor="#FFFFFF" width="100%">
+ <:ifFieldPerm summary:><input type="text" name="summary" maxlength="<:cfg fields summary_size 255:>" size="64" value="<: old summary default summary :>" />
+ <:or:><:default summary:><:eif:></td>
+ <td nowrap="nowrap" bgcolor="#FFFFFF"><:help edit summary:> <:error_img summary:></td>
+ </tr>
<:if Cfg image title:><tr>
<th nowrap="nowrap" bgcolor="#FFFFFF" align="left">Title image:</th>
<td bgcolor="#FFFFFF" width="100%"><:ifFieldPerm titleImage:><:titleImages:> (upload this to
parentid:></td>
</tr>
<tr>
- <th align="left" bgcolor="#FFFFFF">Title*:</th>
+ <th align="left" bgcolor="#FFFFFF">Title:</th>
<td bgcolor="#FFFFFF"><:ifFieldPerm title:><input type="text" name="title" value="<:old title default title:>" size="60"><:or:><:product title:><:eif:> </td>
<td nowrap="nowrap" bgcolor="#FFFFFF"><:help product title:> <:error_img title:></td>
</tr>
<tr>
- <th nowrap="nowrap" align="left" bgcolor="#FFFFFF">Summary*:</th>
+ <th nowrap="nowrap" align="left" bgcolor="#FFFFFF">Summary:</th>
<td nowrap="nowrap" bgcolor="#FFFFFF"><:ifFieldPerm summary:><input type="text" name="summary" value="<:old summary default summary:>" size=60><:or:><:product summary:><:eif:> </td>
<td nowrap="nowrap" bgcolor="#FFFFFF"><:help product summary:> <:error_img
summary:></td>
</tr>
+ <tr>
+ <th nowrap="nowrap" align="left" bgcolor="#FFFFFF">Description:</th>
+ <td nowrap="nowrap" bgcolor="#FFFFFF"><:ifFieldPerm description:><input type="text" name="description" value="<:old description default description:>" size=60><:or:><:product description:><:eif:> </td>
+ <td nowrap="nowrap" bgcolor="#FFFFFF"><:help product description:> <:error_img
+ description:></td>
+ </tr>
+ <tr>
+ <th nowrap="nowrap" align="left" bgcolor="#FFFFFF">Product Code:</th>
+ <td nowrap="nowrap" bgcolor="#FFFFFF"><:ifFieldPerm product_code:><input type="text" name="product_code" value="<:old product_code default product_code:>" size=60><:or:><:product product_code:><:eif:> </td>
+ <td nowrap="nowrap" bgcolor="#FFFFFF"><:help product product_code:> <:error_img
+ product_code:></td>
+ </tr>
<tr>
<th align="left" bgcolor="#FFFFFF" valign="top"> Body:</th>
<td bgcolor="#FFFFFF">
</tr>
<:iterator begin dyncart:>
<tr>
- <td><a href="<:dyncartitem link:>"><:dynreplace [dyncartitem title] (.{15}).* $1...:></a></td>
+ <td><a href="<:dyncartitem link:>"><:dynreplace [dyncartitem title] "((?:&[^;]*;|[^&]){15}).*" $1...:></a></td>
<td class="cartunits"><:dyncartitem units:></td>
<td class="cartprice"><:money dyncartitem retailPrice:></td>
<td class="cartprice"><:money dyncartitem extended:></td>
<td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">
<textarea name="instructions" rows="5" cols="40" wrap="virtual"><:old instructions:></textarea></font><:error_img instructions:></td>
</tr>
+ <tr>
+ <td valign="top"><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Purchase<br />Order:</font></td>
+ <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">
+ <input type="text" name="purchase_order" value="<:old purchase_order:>" /></font><:error_img purchase_order:></td>
+ </tr>
<tr>
<td colspan="2"> <font face="Verdana, Arial, Helvetica, sans-serif" size="2">
* Required information for order to be shipped</font></td>
for my $col (@cols) {
my $sql = $col->{field} . " " . $col->{type};
$sql .= $col->{null} ? ' null' : ' not null';
- if ($col->{default} ne 'NULL') {
+ if ($col->{default} ne 'NULL' &&
+ ($col->{type} =~ /char/i || $col->{default} =~ /\d/)) {
$sql .= " default ";
if ($col->{default} =~ /^\d+$/) {
$sql .= $col->{default};
#!perl -w
use strict;
use BSE::Test ();
-use Test::More tests=>85;
+use Test::More tests=>88;
use File::Spec;
use FindBin;
my $cgidir = File::Spec->catdir(BSE::Test::base_dir, 'cgi-bin');
0
EXPECTED
+template_test "replace complex re", $parent, <<'TEMPLATE', <<EXPECTED;
+<:replace "test&test 01234567890123456789" ((?:&[^;]*;|[^&]){16}).* $1...:>
+TEMPLATE
+test&test 012345...
+EXPECTED
+
############################################################
# Cleanup
# the location of mysql
mysql = mysql
basic.access_control=0
+basic.staticajax=1
basic.sign=0
#basic.htusers = /home/httpd/bsetest/htdocs/images/.htusers
#article uris.9 = /test
site users.billing_on_main_opts=0
#site users.user_register=0
#paths.libraries=/home/tony/dev/bse/tandb_dealer/cvs/modules
-paths.libraries=/home/tony/dev/bse/lib
-basic.custom_class=BSE::Custom::Abberfield
+#paths.libraries=/home/tony/dev/bse/lib
+#paths.libraries=/home/tony/dev/bse/work2/modules
+#basic.custom_class=BSE::Custom::Abberfield
+#basic.custom_class=BSE::CustomTest
#paths.siteuser_passwd=/home/httpd/bsetest/data/supasswd
#custom.user_auth=1
# product fields.retailPrice=Dealer Price Inc GST
#paths.local_templates=/home/tony/dev/bse/tandb_dealer/cvs/templates
+#paths.local_templates=/home/tony/dev/bse/work2/templates
#shop.payment_types=1,2,10,11,12
payment type names.10=DirectDeposit
payment type names.11=FaxProForma
payment type names.12=EmailProForma
payment type required.11=facsimile
-paths.local_templates=/home/tony/dev/bse/work/templates/
+#paths.local_templates=/home/tony/dev/bse/work/templates/
affiliate.prompt_name=1
site users.require_affiliate_name=0
admin group template sets.test=Test Templates
html.msentify=1
-html.ajaxcharset=1
+#html.ajaxcharset=1
+html.mbcs=1
debug.convert_charset=1
+html.charset=windows-1252
popink.payment_email=tony@develop-help.com
popink.errorsto=tony@develop-help.com
includes.99cfg=cfg/
permission full_access.permissions=*
+
+search index scores.product_code=5