|
|
Dear All,
In case you want to be the first one on your block to support
the newly-announced ECML, I have made up a little module.
It takes the now-standard MiniVend checkout form names and
maps them.
To use, just copy the included ECML.pm to lib/Vend, and
then put in your minivend.cfg:
UserTag ecml Order name function
UserTag ecml posNumber 2
UserTag ecml addAttr
UserTag ecml Routine <<EOR
sub {
#::logError("ecml raw: @_");
use Vend::ECML;
Vend::ECML::ecml(@_);
}
EOR
In your checkout form, you put things like:
[ecml fname]
[ecml lname]
[ecml address]
and of course:
[ecml name=country options="US=United States, CA=Canada"]
which should automagically pull names out of country.asc. 8-)
I have attached a MV3.14 checkout form with some of the fields
put in.
Somewhere in the form, you will see:
<INPUT TYPE=hidden NAME=mv_click CHECKED VALUE="ECML_map">
[set ECML_map]
[ecml function=mapback]
[/set]
This maps the form inputs back into the old-style variables.
Hope you enjoy leading the pack!
--
Mike Heins http://www.minivend.com/ ___
Internet Robotics |_ _|____
131 Willow Lane, Floor 2 | || _ \
It's a little-known fact Oxford, OH 45056 | || |_) |
that the Y1K problem caused <mikeh@minivend.com> |___| _ <
the Dark Ages. -- unknown 513.523.7621 FAX 7501 |_| \_\
#!/usr/bin/perl
# Vend::ECML -- map MiniVend forms/userdb to ECML checkout
package Vend::ECML;
use vars qw/$VERSION/;
use strict;
$VERSION = '0.01';
sub version {
return $VERSION;
}
my $warnsave = $^W;
$^W = 0;
my $ecml_comment_map = <<EOF;
title Ecom_ShipTo_Postal_Name_Prefix 4
first name Ecom_ShipTo_Postal_Name_First 15
middle name Ecom_ShipTo_Postal_Name_Middle 15
last name Ecom_ShipTo_Postal_Name_Last 15
name suffix Ecom_ShipTo_Postal_Name_Suffix 4
street1 Ecom_ShipTo_Postal_Street_Line1 20
street2 Ecom_ShipTo_Postal_Street_Line2 20
street3 Ecom_ShipTo_Postal_Street_Line3 20
city Ecom_ShipTo_Postal_City 22
state or province Ecom_ShipTo_Postal_StateProv 2
zip or postal code Ecom_ShipTo_Postal_PostalCode 14
country Ecom_ShipTo_Postal_CountryCode 2
phone Ecom_ShipTo_Telecom_Phone_Number 10
email Ecom_ShipTo_Online_Email 40
title Ecom_BillTo_Postal_Name_Prefix 4
first name Ecom_BillTo_Postal_Name_First 15
middle name Ecom_BillTo_Postal_Name_Middle 15
last name Ecom_BillTo_Postal_Name_Last 15
name suffix Ecom_BillTo_Postal_Name_Suffix 4
street1 Ecom_BillTo_Postal_Street_Line1 20
street2 Ecom_BillTo_Postal_Street_Line2 20
street3 Ecom_BillTo_Postal_Street_Line3 20
city Ecom_BillTo_Postal_City 22
state or province Ecom_BillTo_Postal_StateProv 2
zip or postal code Ecom_BillTo_Postal_PostalCode 14
country Ecom_BillTo_Postal_CountryCode 2
phone Ecom_BillTo_Telecom_Phone_Number 10
email Ecom_BillTo_Online_Email 40
title Ecom_ReceiptTo_Postal_Name_Prefix 4
first name Ecom_ReceiptTo_Postal_Name_First 15
middle name Ecom_ReceiptTo_Postal_Name_Middle 15
last name Ecom_ReceiptTo_Postal_Name_Last 15
name suffix Ecom_ReceiptTo_Postal_Name_Suffix 4
street1 Ecom_ReceiptTo_Postal_Street_Line1 20
street2 Ecom_ReceiptTo_Postal_Street_Line2 20
street3 Ecom_ReceiptTo_Postal_Street_Line3 20
city Ecom_ReceiptTo_Postal_City 22
state or province Ecom_ReceiptTo_Postal_StateProv 2
zip or postal code Ecom_ReceiptTo_Postal_PostalCode 14
country Ecom_ReceiptTo_Postal_CountryCode 2
phone Ecom_ReceiptTo_Telecom_Phone_Number 10
email Ecom_ReceiptTo_Online_Email 40
card Ecom_Payment_Card_Name 30
card type Ecom_Payment_Card_Type 4
card number Ecom_Payment_Card_Number 19
cardholder verification value Ecom_Payment_Card_Verification 4
card expiration date day Ecom_Payment_Card_ExpDate_Day 2
card expiration date month Ecom_Payment_Card_ExpDate_Month 2
card expiration date year Ecom_Payment_Card_ExpDate_Year 4
payment protocols available Ecom_Payment_Card_Protocol 20
consumer generated order ID Ecom_ConsumerOrderID 20
schema version number Ecom_SchemaVersion 30
end transaction flag Ecom_TransactionComplete
EOF
my $ecml_field_map = <<EOF;
title Ecom_ShipTo_Postal_Name_Prefix 4
name Ecom_ShipTo_Postal_Name_Combined 40
fname Ecom_ShipTo_Postal_Name_First 20
mname Ecom_ShipTo_Postal_Name_Middle 3
lname Ecom_ShipTo_Postal_Name_Last 20
name_suffix Ecom_ShipTo_Postal_Name_Suffix 4
address Ecom_ShipTo_Postal_Street_Line1 30
address1 Ecom_ShipTo_Postal_Street_Line1 30
address2 Ecom_ShipTo_Postal_Street_Line2 30
address3 Ecom_ShipTo_Postal_Street_Line3 30
city Ecom_ShipTo_Postal_City 22
state Ecom_ShipTo_Postal_StateProv 2
zip Ecom_ShipTo_Postal_PostalCode 14
country Ecom_ShipTo_Postal_CountryCode 2 select country
phone_day Ecom_ShipTo_Telecom_Phone_Number 14
phone Ecom_ShipTo_Telecom_Phone_Number 14
email Ecom_ShipTo_Online_Email 40
b_title Ecom_BillTo_Postal_Name_Prefix 4
b_fname Ecom_BillTo_Postal_Name_First 15
b_mname Ecom_BillTo_Postal_Name_Middle 15
b_lname Ecom_BillTo_Postal_Name_Last 15
b_name_suffix Ecom_BillTo_Postal_Name_Suffix 4
b_address Ecom_BillTo_Postal_Street_Line1 20
b_address1 Ecom_BillTo_Postal_Street_Line1 20
b_address2 Ecom_BillTo_Postal_Street_Line2 20
b_address3 Ecom_BillTo_Postal_Street_Line3 20
b_city Ecom_BillTo_Postal_City 22
b_state Ecom_BillTo_Postal_StateProv 2
b_zip Ecom_BillTo_Postal_PostalCode 14
b_country Ecom_BillTo_Postal_CountryCode 2
b_phone Ecom_BillTo_Telecom_Phone_Number 14
b_phone_day Ecom_BillTo_Telecom_Phone_Number 14
b_email Ecom_BillTo_Online_Email 40
r_title Ecom_ReceiptTo_Postal_Name_Prefix 4
r_fname Ecom_ReceiptTo_Postal_Name_First 15
r_mname Ecom_ReceiptTo_Postal_Name_Middle 15
r_lname Ecom_ReceiptTo_Postal_Name_Last 15
r_name_suffix Ecom_ReceiptTo_Postal_Name_Suffix 4
r_address1 Ecom_ReceiptTo_Postal_Street_Line1 20
r_address2 Ecom_ReceiptTo_Postal_Street_Line2 20
r_address3 Ecom_ReceiptTo_Postal_Street_Line3 20
r_city Ecom_ReceiptTo_Postal_City 22
r_state Ecom_ReceiptTo_Postal_StateProv 2
r_zip Ecom_ReceiptTo_Postal_PostalCode 14
r_country Ecom_ReceiptTo_Postal_CountryCode 2
r_phone_day Ecom_ReceiptTo_Telecom_Phone_Number 10
r_phone Ecom_ReceiptTo_Telecom_Phone_Number 10
r_email Ecom_ReceiptTo_Online_Email 40
c_name Ecom_Payment_Card_Name 30
mv_credit_card_type Ecom_Payment_Card_Type 4
mv_credit_card_number Ecom_Payment_Card_Number 19
mv_credit_card_verify Ecom_Payment_Card_Verification 4
mv_credit_card_exp_day Ecom_Payment_Card_ExpDate_Day 2
mv_credit_card_exp_month Ecom_Payment_Card_ExpDate_Month 2
mv_credit_card_exp_year Ecom_Payment_Card_ExpDate_Year 4
payment_protocols_available Ecom_Payment_Card_Protocol 20
mv_order_number Ecom_ConsumerOrderID 20
ecml_version Ecom_SchemaVersion 30
end_transaction_flag Ecom_TransactionComplete 1
EOF
$ecml_comment_map =~ s/\s+$//;
$ecml_field_map =~ s/\s+$//;
my (@comments) = split /\n/, $ecml_comment_map;
my (@fields) = split /\n/, $ecml_field_map;
my $ECML = {};
for(@comments) {
my ($comment, $ecml, $min_length) = split /\t/, $_;
$ECML->{$ecml} = {} unless $ECML->{$ecml};
$ECML->{$ecml}->{ecml} = $ecml;
$ECML->{$ecml}->{comment} = $comment;
}
for(@fields) {
my ($map_to, $ecml, $size, $widget, $db, $name, $attribute, $outboard) = split /\t/, $_;
$ECML->{$ecml} = {} unless $ECML->{$ecml};
my $ref = $ECML->{$ecml} || {};
$ref->{ecml} = $ecml;
$ref->{map_to} = $map_to;
$ref->{size} = $size if $size;
$ref->{widget} = $widget || '';
$ref->{db} = $db || '';
$ref->{attribute} = $attribute || '';
$ref->{name} = $name || '';
$ECML->{$map_to} = $ref;
}
$^W = $warnsave;
sub output_ecml_database {
my $out = "ecml\tmap_to\tlength\tcomment\twidget\tdb\tattribute\tname\n";
for (keys %$ECML) {
$out .= join "\t", @{$ECML->{$_}}{qw/ ecml map_to length comment widget db attribute name/};
$out .= "\n";
$out .= join "\t", @{$ECML->{$_}}{qw/ map_to ecml length comment widget db attribute name/};
$out .= "\n";
}
return $out;
}
sub widget {
my ($self) = @_;
if(! $self->{name}) {
$self->{ecml_error} = "no name passed for widget";
return undef;
}
my $def = defined $ECML->{$self->{name}}
? $ECML->{$self->{name}}
: {};
#::logError(Vend::Util::uneval($def));
my $name = defined $def->{ecml}
? $def->{ecml}
: $self->{name};
my $run = '';
my ($len, $type, $value, $maxlength, $size, $fname, $extra, $select);
$fname = $name;
if($fname =~ /\W/) {
$fname =~ s/"/"/g;
$fname = qq{"$fname"};
}
unless($self->{clear}) {
$value = $self->{value} || $::Values->{$name}
|| $::Values->{$self->{name}}
|| '';
}
else {
$value = '';
}
if(! $def->{widget} || "\L$def->{widget}" eq 'text') {
$size = $self->{size} || $def->{size} || '40';
$extra = defined $self->{extra} ? " $self->{extra}" : '';
$value =~ s/"/"/g;
$run = qq{<INPUT NAME=$name VALUE="$value" SIZE=$size$extra>};
}
elsif ($def->{widget} eq 'select') {
$run .= qq{<SELECT NAME=$fname};
$run .= ' MULTIPLE' if Vend::Util::is_yes($self->{multiple});
$run .= " SIZE=$size" if defined $self->{size};
$run .= '>';
my @opts;
if($self->{options}) {
@opts = split /\s*,\s*/, $self->{options};
}
if($def->{db}) {
my $label = $self->{label_field} || 'name';
my $args = '';
$args .= <<EOF;
fi=$def->{db}
ra=yes
rf=0,$label
tf=$label
ml=1000
rd==
EOF
my $optlist = Vend::Interpolate::tag_search($args);
$optlist =~ s/\s+$//;
$optlist =~ s/^\s+//;
push (@opts, split /\n+/, $optlist);
}
if($self->{none}) {
unshift(@opts, "= -- NONE --");
}
my $default = $value;
for (@opts) {
$run .= '<OPTION';
$select = '';
s/\*$// and $select = 1;
if ($default) {
$select = '';
}
my ($value,$label) = split /=/, $_, 2;
if($label) {
$value =~ s/"/"/;
$run .= qq| VALUE="$value"|;
}
if ($default) {
my $regex = quotemeta $value;
$default =~ /(?:\0|^)$regex(?:\0|$)/ and $select = 1;
}
$run .= ' SELECTED' if $select;
$run .= '>';
if($label) {
$run .= $label;
}
else {
$run .= $value;
}
}
$run .= '</SELECT>';
}
return $run;
}
sub mapback {
my @targets = grep /^Ecom_/, keys %$ECML;
for (@targets) {
next unless defined $CGI::values{$_};
$CGI::values{$ECML->{$_}{map_to}} = $CGI::values{$_};
}
return '';
}
sub new {
my ($class, $opt) = @_;
$opt = {} unless $opt;
return bless $opt, $class;
}
sub ecml {
my ($name, $function, $opt) = @_;
#::logError("ecml name=$name func=$function opt=$opt");
my $self = new Vend::ECML $opt;
$self->{name} = $name if $name;
$function = 'widget' unless $function;
$self->{function} = $function;
unless ($self->can($function) ) {
::logError("unknown ECML function $function");
$::Scratch->{mv_ecml_error} = logError("unknown ECML function $function");
undef $::Scratch->{mv_ecml_status};
return undef unless $opt->{show};
return $::Scratch->{mv_ecml_error};
}
#::logError(Vend::Util::uneval($self));
my $status = $self->$function();
if(! $status) {
$::Scratch->{mv_ecml_error} = $self->{failure}
|| $self->{ecml_error}
|| "$function failed";
return $::Scratch->{mv_ecml_error} if $self->{show};
return $status unless $self->{hide};
return '';
}
$::Scratch->{mv_ecml_message} = $self->{success};
return $self->{success} if $self->{show};
return '' if $self->{hide};
return $status;
}
1;
Title: [L]Check out[/L] -- __COMPANY__
|
[include pages/logobar]
[if session logged_in]
[then]
[set [L]Log out[/L]]
mv_todo=return
mv_nextpage=ord/checkout
[userdb function=logout clear=1]
[/set]
[data session failure] [/if] [L]If you have an account with us, please enter your user name and password[/L]. (test/test for testing) [/else][/if]
|