Name

SpecialSub — specify Perl subroutines to handle certain events or conditions

SYNOPSIS

event_name subroutine_name...

DESCRIPTION

The directive specifies Perl subroutines that should be called to handle certain events. The available events are described below.

Request (request_init)

Event triggered on every request, right after catalog selection and before session assignment.

Request (admin_init)

Event triggered on every request for users with administrator privileges, request, after initialization of embedded Perl objects. This allows catalog subroutines to be specified as request handlers and have properly initialized session variables by the time they run.

Debug Qualify (debug_qualify)

Event triggered to determine whether debug mode should be enabled for the incoming client connection. Have in mind that simple, host-based decision can be made by using the DebugHost configuration directive. The debug_qualify specialSub is invoked only if DebugHost is either undefined, or the client host is found in the DebugHost list. See debug glossary entry for a complete discussion.

Flypage (flypage)

Event triggered for determining the result set for the flypage.

Credit Card Type (guess_cc_type)

Event triggered at the time of deriving credit card type, MV_CREDIT_CARD_TYPE. Interchange already recognizes major credit card types but local areas might require you to write custom recognition code. The subroutine is called with the credit card number. A true return value should contain the recognized credit card type name. A false value indicates that the number recognition did not succeed, and that Interchange should proceed with its built-in detection algorithm.

Session Creation (init_session)

Event triggered at new session creation time. The subroutine is called with the pointer to the newly created session variables space. Subroutine return value is not used.

Lockout (lockout)

Event triggered for locking out a bad web spider or misbehaving client (see RobotLimit). The subroutine is called without parameters and is expected to perform all the necessary custom steps. It should exit with an appropriate return value to signal how the rest of the process should be handled.

A true return value indicates that no more handling is needed. A false value indicates that Interchange should continue and execute the default, built-in action lockout action, which is specified by the LockoutCommand config directive.

Missing page (missing)

Event triggered when a requested Interchange page is missing. The subroutine is called with the name of the missing page and is expected to perform all the necessary custom handling. It should exit with an appropriate return value to signal how the rest of the process should be handled.

A true return value will indicates that all actions (including the response to the client) have been performed by your function and no more handling is needed. You can also return an array, (1, PAGENAME), where PAGENAME is the page to be displayed to the user.

A false return value indicates that Interchange should continue and execute the default, built-in action, which is displaying a page specified by "SpecialPage missing".

Missing product (order_missing)

Event triggered when a missing product is been added to the shopping cart.

A true return value will suppress the log message about this event.

Shipping calculation (shipping_callout)

Event is triggered after shipping calculation, but before result is formatted and returned.

It's useful for the type of customization that would require modifying too many shipping table entries or using entirely custom shipping code, because it allows you to build on the powerful shipping features interchange already has.

Weight calculation (weight_callout)

Event is triggered after weight is processed for shipping calculation.

The subroutine is called with the weight as parameter and expects the modified weight as return value.

It does not affect other calculations, such as done by the [weight] usertag.

DIRECTIVE TYPE AND DEFAULT VALUE

Catalog directive

EXAMPLES

Example: Defining "SpecialSub missing"

In the event of a missing page, see if the "page name" could be understood as "product group/category". If it could, use the provided information to construct the search specification and invoke the search results page. (More about Interchange search facilities can be read in Interchange Guides: Search Tutorial). If it couldn't, return a false value and proceed to display "SpecialPage missing".

Put the following in catalog.cfg:

SpecialSub  missing  check_category

Sub check_category <<EOS
  sub {
    my ($name) = @_;
    return unless $name =~ m{^[A-Z]};
    $name =~ s,_, ,g;
    my ($prod_group, $category) = split m{/}, $name;

    $CGI->{co} = 1;
    $CGI->{fi} = 'products';
    $CGI->{st} = 'db';
    $CGI->{sf} = join "\0", 'prod_group', 'category';
    $CGI->{op} = join "\0", 'eq', 'eq';
    $CGI->{se} = join "\0", $prod_group, $category;
    $CGI->{sp} = 'results';
    $CGI->{mv_todo} = 'search';
    $Tag->update('process');

    return (1, 'results');
  }
EOS

Example: Defining SpecialSub init_session

If a client is coming from a "blacklisted" IP address, define variable "blacklist" in its session.

At a later stage, "blacklisted" sessions could be prevented from checking out and finalizing the order, as they are likely to be fraudulent.

SpecialSub  init_session  check_blacklist

Sub check_blacklist <<EOS
  sub {
    my ($session) = @_;

    if ( grep { $CGI::remote_addr } @blacklisted_IPs ) {
      $session->{blacklist} = 1;
    }

    return;
  }
EOS

Example: Defining SpecialSub guess_cc_type

If the credit card number starts with "41", recognize it as type "LOCAL_TYPE". Otherwise, return a false value and implicitly instruct Interchange to continue with the built-in credit card type detection mechanism.

Put the following in catalog.cfg:

SpecialSub  guess_cc_type  check_cc

Sub check_cc <<EOS
  sub {
    my $num = shift;
    return 'LOCAL_TYPE' if $num =~ /^41/;
    return;
  }
EOS

Example: Defining SpecialSub admin_init

Put the following in catalog.cfg:

SpecialSub  admin_init on_admin_init

Sub on_admin_init <<EOS
sub {
  unless ($Session->{username} eq 'foundation') {
    $Variable->{MV_MENU_DIRECTORY} = 'include/foundation/menus';
  }
}
EOS

Example: Shipping discount for dealers with SpecialSub shipping_callout

Sub custom_shipping <<EOS
sub {
    my ($final, $mode, $opt, $o) = @_;
    $final *= .90 if $Scratch->{dealer} and $mode =~ /UPS/i;
    return $final;
}
EOS
SpecialSub shipping_callout custom_shipping

Example: Adjusting shipping weight with SpecialSub weight_callout

Sub custom_weight <<EOS
sub {
    my ($normal_weight) = @_;

    my $new_weight = 0;
    for my $item (@$Items) {
        $new_weight += $item->{weight} * $item->{quantity}
            unless $item->{is_free_shipping};
    }
    return $new_weight;
}
EOS
SpecialSub weight_callout custom_weight

NOTES

If the examples above, the Perl subroutines have been defined on a catalog level, using Sub configuration directive. Interchange catalogs (and everything configured within them) are subject to safe restrictions, so your Sub blocks might have insufficient permissions to execute all of your commands. To solve that problem, either relax the restrictions by using SafeUntrap, or define the subroutines at the global level (in interchange.cfg) using unrestricted GlobalSubs.

As a misnomer, SpecialSub catalog_init was renamed to request_init in Interchange 5.5.2.

AVAILABILITY

SpecialSub is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0:

Source: lib/Vend/Config.pm
Line 633

['SpecialSub',       'hash',       ''],

Source: lib/Vend/Config.pm
Line 3188 (context shows lines 3188-3205)

sub parse_hash {
my($item,$settings) = @_;
if (! $settings) {
  return $HashDefaultBlank{$item} ? '' : {};
}

my $c;

if(defined $C) {
  $c = $C->{$item} || {};
}
else {
  no strict 'refs';
  $c = ${"Global::$item"} || {};
}

return hash_string($settings,$c);
}

AUTHORS

Mike Heins Stefan Hornburg (Racke)

SEE ALSO

shipping(7ic)

DocBook! Interchange!