SpecialSub — specify Perl subroutines to handle certain events or conditions
The directive specifies Perl subroutines that should be called to handle certain events. The available events are described below.
request_init
)Event triggered on every request, right after catalog selection and before session assignment.
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
)
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.
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.
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
)
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
)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
".
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_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_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.
Example: Defining "SpecialSub missing"
In the event of a missing page, see if the "page name" could be understood as
"
". 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
"product group
/category
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
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 GlobalSub
s.
As a misnomer, SpecialSub catalog_init
was
renamed to request_init
in Interchange 5.5.2.
Interchange 5.9.0:
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); }