Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
295 lines (272 sloc) 9.25 KB
__NAME__ purpose
specify Perl subroutines to handle certain events or conditions
__END__
__NAME__ synopsis
<arg choice='plain'><replaceable>event_name</replaceable></arg>
<arg choice='plain' rep='repeat'><replaceable>subroutine_name</replaceable></arg>
__END__
__NAME__ description
<para>
The directive specifies &PERL; subroutines that should be called to
handle certain events. The available events are described below.
</para>
<refsect2>
<title>Request (<literal>request_init</literal>)</title>
<para>
Event triggered on every request, right after catalog
selection and before &glos-session; assignment.
</para>
</refsect2>
<refsect2>
<title>Request (<literal>admin_init</literal>)</title>
<para>
Event triggered on every request for users with administrator privileges,
request, after initialization of embedded Perl objects. This allows
&glos-catalog; subroutines to be specified as request handlers and have
properly initialized &glos-session; variables by the time they run.
</para>
</refsect2>
<refsect2>
<title>Debug Qualify (<literal>debug_qualify</literal>)</title>
<para>
Event triggered to determine whether &glos-debug; mode should be
enabled for the incoming client connection. Have in mind that simple,
host-based decision can be made by using the &conf-DebugHost;
configuration directive. The <literal>debug_qualify</literal>
specialSub is invoked only if &conf-DebugHost; is either undefined,
or the client host is found in the &conf-DebugHost; list.
See &glos-debug; glossary entry for a complete discussion.
</para>
</refsect2>
<refsect2>
<title>Flypage (<literal>flypage</literal>)</title>
<para>
Event triggered for determining the result set for the flypage.
<!-- TODO more info -->
</para>
</refsect2>
<refsect2>
<title>Credit Card Type (<literal>guess_cc_type</literal>)</title>
<para>
Event triggered at the time
of deriving credit card type, &var-MV_CREDIT_CARD_TYPE;.
&IC; 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 &glos-true; return value should contain the recognized credit card
type name.
A &glos-false; value indicates that the number recognition did not
succeed, and that &IC; should proceed with its built-in detection
algorithm.
</para>
</refsect2>
<refsect2>
<title>Session Creation (<literal>init_session</literal>)</title>
<para>
Event triggered at new &glos-session; creation time.
The subroutine is called with the pointer to the newly created
&glos-session; variables space. Subroutine return value is not used.
</para>
</refsect2>
<refsect2>
<title>Lockout (<literal>lockout</literal>)</title>
<para>
Event triggered for locking out a bad web spider or misbehaving
client (see &conf-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.
</para>
<para>
A &glos-true; return value indicates that no more handling is
needed. A &glos-false; value indicates that &IC; should continue
and execute the default, built-in action lockout action, which
is specified by the &conf-LockoutCommand; config directive.
<!-- TODO : Where do you read IP or something from ? -->
</para>
</refsect2>
<refsect2>
<title>Missing page (<literal>missing</literal>)</title>
<para>
Event triggered when a requested &IC; 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.
</para><para>
A &glos-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, <replaceable>PAGENAME</replaceable>), where
<replaceable>PAGENAME</replaceable> is the page to be displayed to the user.
</para><para>
A &glos-false; return value indicates that &IC; should continue
and execute the default, built-in action, which
is displaying a page specified by "&conf-SpecialPage;
<literal>missing</literal>".
</para>
</refsect2>
<refsect2>
<title>Missing product (<literal>order_missing</literal>)</title>
<para>
Event triggered when a missing product is been added to the shopping
cart.
</para>
<para>
A &glos-true; return value will suppress the log message about this event.
</para>
</refsect2>
<refsect2>
<title>Shipping calculation (<literal>shipping_callout</literal>)</title>
<para>
Event is triggered after shipping calculation, but before result is
formatted and returned.
</para>
<para>
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.
</para>
</refsect2>
<refsect2>
<title>Weight calculation (<literal>weight_callout</literal>)</title>
<para>
Event is triggered after weight is processed for shipping calculation.
</para>
The subroutine is called with the weight as parameter and expects the modified weight as return value.
<para>
It does not affect other calculations, such as done by the <tag>weight</tag>
usertag.
</para>
</refsect2>
__END__
__NAME__ notes
If the examples above, the &PERL; subroutines have been defined on a
&glos-catalog; level, using &conf-Sub; configuration directive.
&IC; catalogs (and everything configured within them) are subject to
&glos-safe; restrictions, so your &conf-Sub; blocks might have
insufficient permissions to execute all of your commands. To solve that
problem, either relax the restrictions by using &conf-SafeUntrap;,
or define the subroutines at the global level (in &gcf;) using
unrestricted &conf-GlobalSub;s.
</para><para>
As a misnomer, SpecialSub <literal>catalog_init</literal> was
renamed to <literal>request_init</literal> in &IC; 5.5.2.
__END__
__NAME__ example: Defining "SpecialSub missing"
In the event of a missing page, see if the "page name" could be understood as
"<literal><replaceable>product group</replaceable>/<replaceable>category</replaceable></literal>". If it could, use the provided information to construct
the search specification and invoke the search results page.
(More about &IC; search facilities can be read in <olink targetdoc='search'/>).
If it couldn't, return a &glos-false; value and proceed to display
"&conf-SpecialPage; <literal>missing</literal>".
</para><para>
Put the following in &ccf;:
<programlisting><![CDATA[
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
]]></programlisting>
__END__
__NAME__ example: Defining SpecialSub init_session
If a client is coming from a "blacklisted" IP address, define
variable "blacklist" in its session.
</para><para>
At a later stage, "blacklisted" sessions could be prevented from
checking out and finalizing the order, as they are
likely to be fraudulent.
</para><para>
<programlisting><![CDATA[
SpecialSub init_session check_blacklist
Sub check_blacklist <<EOS
sub {
my ($session) = @_;
if ( grep { $CGI::remote_addr } @blacklisted_IPs ) {
$session->{blacklist} = 1;
}
return;
}
EOS
]]></programlisting>
__END__
__NAME__ example: Defining SpecialSub guess_cc_type
If the credit card number starts with "<literal>41</literal>",
recognize it as type "<literal>LOCAL_TYPE</literal>". Otherwise,
return a false value and implicitly instruct &IC; to continue with
the built-in credit card type detection mechanism.
</para><para>
Put the following in &ccf;:
<programlisting><![CDATA[
SpecialSub guess_cc_type check_cc
Sub check_cc <<EOS
sub {
my $num = shift;
return 'LOCAL_TYPE' if $num =~ /^41/;
return;
}
EOS
]]></programlisting>
__END__
__NAME__ example: Defining SpecialSub admin_init
Put the following in &ccf;:
<programlisting><![CDATA[
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
]]></programlisting>
__END__
__NAME__ example: Shipping discount for dealers with SpecialSub shipping_callout
<programlisting><![CDATA[
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
]]></programlisting>
__END__
__NAME__ example: Adjusting shipping weight with SpecialSub weight_callout
<programlisting><![CDATA[
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
]]></programlisting>
__END__
__NAME__ author
&mheins;
&racke;
__END__