4.1. Advanced Multi-level Order Pages

An unlimited number of order checking profiles can be defined with the OrderProfile directive, or by defining order profiles in scratch variables. This allows a multi-level ordering process, with checking for format and validity at every stage.

To custom-configure the error message, place it after the format check requirement.

Specifications take the form of an order page variable (like name or address), followed by an equals sign and one of five check types:

required

mandatory

phone

phone_us

state

province

state_province

zip

ca_postcode

postcode

true

false

email

regex

            foo=regex ^bar
       foo=regex ^bar "You must have bar at the beginning of this"
       foo=regex !^bar "You may not have bar at the beginning!"

length

       foo=length 4-10

unique

       foo=unique userdb Sorry, that username is already taken

filter

       foo=filter entities Sorry, no HTML allowed
            foo=filter lower Sorry, no uppercase characters

Also, there are pragmas that can be used to change behavior:

&charge

&credit_card

        # Checks credit card number and destroys number after encryption
        # The charge operation can never work
    
        &credit_card=standard
        &charge=custom authorizenet
    
        # Checks credit card number and keeps number after encryption
        # The charge operation can now work
    
        &credit_card=standard keep
        &charge=custom authorizenet
        &credit_card=check_cc

&fail

        &fail=page4

&fatal

&final

&update

&return

        # Success :)
        &return 1
    
        # Failure :\
        &return 0

&set

&setcheck

&success

        &success=page5

As an added measure of control, the specification is evaluated for the special Interchange tags to provide conditional setting of order parameters. With the [perl] [/perl] capability, quite complex checks can be done. Also, the name of the page to be displayed on an error can be set in the mv_failpage variable.

The following file specifies a simple check of formatted parameters:

 name=required You must give us your name.
 address=required Oops! No address.
 city=required
 state=required
 zip=required
 email=required
 phone_day=phone_us XXX-XXX-XXXX phone-number for US or Canada
 &fatal=yes
 email=email Email address missing the domain?
 &set=mv_email [value email]
 &set=mv_successpage ord/shipping

The profile above only performs the &set directives if all of the previous checks have passed -- the &fatal=yes will stop processing after the check of the email address if any of the previous checks failed.

If you want to place multiple order profiles in the same file, separate them with __END__, which must be on a line by itself.

User-defined check routines can be defined in a GlobalSub:

    GlobalSub <<EOF
    sub set_up_extra_check {
        BEGIN {
            package Vend::Order;
            sub _pt_postcode {
                # $ref is to Vend::Session->{'values'} hash
                # $var is the passed name of the variable
                # $val is current value of checked variable
                my($ref, $var, $val) = @_;

                if ($ref->{country} =~ /^(PT|portugal)$/i) {
                    return $val =~ /^\d\d\d\d$/ ?
                        (1, $var, '') : (undef, $var, "not a Portugese postal code");
                }
                else {
                    return (1, $var, '');
                }
            }
        }
    }
    EOF

Now you can specify in an order profile:

  postcode=pt_postcode

Very elaborate checks are possible. There must be an underscore preceding the routine name. The return value of the subroutine should be a three-element array, consisting of:

  1. the pass/fail ('1' or 'undef') status of the check;
  2. the name of the variable which was checked;
  3. a standard error message for the failure, in case a custom one has not been specified in the order profile.

The latter two elements are used by the [error] tag for on-screen display of form errors. The checkout page of the Foundation demo includes examples of this.