ItemAction — specify subroutine to invoke when users' electronic cart contents change
The directive specifies name of the Perl subroutine to be invoked when users' electronic cart contents change. The subroutine can be defined on both global and catalog level.
The subroutine executes whenever the contents of users' cart are changed via the standard means available through the CGI variable space.
The subroutine will be executed per-change, such that any page process resulting in multiple alterations to the cart will potentially call this function multiple times.
The specified function is invoked with the reference to the cart item in question. The function's return value is not used.
It must be noted that the Interchange cart subsystem is based on arrayrefs of hashrefs (all Perl programming terms) — there is no object encapsulation for limiting or monitoring program access to the contents of any cart. Consequently, direct manipulation of the cart from within Perl will not cause this function to be invoked. The triggers only fire when the cart contents are modified through the standard Interchange CGI-based variable processing. Therefore, it is assumed that any programmer sufficiently comfortable or confident to manipulate cart contents directly can also be given the responsibility of deciding whether or not it is appropriate to manually invoke this function.
This configuration directive is very similar to CartTrigger
and CartTriggerQuantity
, the two more recent and flexible options.
Interchange 5.9.0:
Source: lib/Vend/Config.pm
Line 2161 (context shows lines 2161-2258)
sub parse_action { my ($var, $value, $mapped) = @_; if (! $value) { return $InitializeEmpty{$var} ? '' : {}; } return if $Vend::ExternalProgram; my $c; if($mapped) { $c = $mapped; } elsif(defined $C) { $c = $C->{$var} ||= {}; } else { no strict 'refs'; $c = ${"Global::$var"} ||= {}; } if (defined $C and ! $c->{_mvsafe}) { my $calc = Vend::Interpolate::reset_calc(); $c->{_mvsafe} = $calc; } my ($name, $sub) = split /\s+/, $value, 2; $name =~ s/-/_/g; ## Determine if we are in a catalog config, and if ## perl should be global and/or strict my $nostrict; my $perlglobal = 1; if($C) { $nostrict = $Global::PerlNoStrict->{$C->{CatalogName}}; $perlglobal = $Global::AllowGlobal->{$C->{CatalogName}}; } # Untaint and strip this pup $sub =~ s/^\s*((?s:.)*\S)\s*//; $sub = $1; if($sub !~ /\s/) { no strict 'refs'; if($sub =~ /::/ and ! $C) { $c->{$name} = \&{"$sub"}; } else { if($C and $C->{Sub}) { $c->{$name} = $C->{Sub}{$sub}; } if(! $c->{$name} and $Global::GlobalSub) { $c->{$name} = $Global::GlobalSub->{$sub}; } } if(! $c->{$name} and $AllowScalarAction{$var}) { $c->{$name} = $sub; } elsif(! $c->{$name}) { $@ = errmsg("Mapped %s action routine '%s' is non-existent.", $var, $sub); } } elsif ( ! $mapped and $sub !~ /^sub\b/) { if($AllowScalarAction{$var}) { $c->{$name} = $sub; } else { my $code = <<EOF; sub { return Vend::Interpolate::interpolate_html(<<EndOfThisHaiRYTHING); $sub EndOfThisHaiRYTHING } EOF $c->{$name} = eval $code; } } elsif ($perlglobal) { package Vend::Interpolate; if($nostrict) { no strict; $c->{$name} = eval $sub; } else { $c->{$name} = eval $sub; } } else { package Vend::Interpolate; $c->{$name} = $c->{_mvsafe}->reval($sub); } if($@) { config_warn("Action '%s' did not compile correctly (%s).", $name, $@); } return $c; }