package PDF::Template::Container::Conditional;
#GGG Convert <conditional> to be a special case of <switch>?
use strict;
BEGIN {
use vars qw(@ISA);
@ISA = qw(PDF::Template::Container);
use PDF::Template::Container;
}
my %isOp = (
'=' => '==',
(map { $_ => $_ } ( '>', '<', '==', '!=', '>=', '<=' )),
(map { $_ => $_ } ( 'gt', 'lt', 'eq', 'ne', 'ge', 'le' )),
);
# This cannot be within a should_render() function because the conditional needs
# to return true even if the conditional is false. We are indicating that this
# branch has done everything it needs to do, not that this branch is calling for
# a pagebreak.
sub conditional_passes
{
my $self = shift;
my ($context) = @_;
my $name = $context->get($self, 'NAME');
return 0 unless $name =~ /\S/;
my $val = $context->param($name);
$val = @{$val} while UNIVERSAL::isa($val, 'ARRAY');
$val = ${$val} while UNIVERSAL::isa($val, 'SCALAR');
my $value = $context->get($self, 'VALUE');
if (defined $value)
{
my $op = $context->get($self, 'OP');
$op = defined $op && exists $isOp{$op}
? $isOp{$op}
: '==';
# Force numerical context on both values;
$value *= 1;
$val *= 1;
my $res;
for ($op)
{
/^>$/ && do { $res = ($val > $value); last };
/^<$/ && do { $res = ($val < $value); last };
/^==$/ && do { $res = ($val == $value); last };
/^!=$/ && do { $res = ($val != $value); last };
/^>=$/ && do { $res = ($val >= $value); last };
/^<=$/ && do { $res = ($val <= $value); last };
/^gt$/ && do { $res = ($val gt $value); last };
/^lt$/ && do { $res = ($val lt $value); last };
/^eq$/ && do { $res = ($val eq $value); last };
/^ne$/ && do { $res = ($val ne $value); last };
/^ge$/ && do { $res = ($val ge $value); last };
/^le$/ && do { $res = ($val le $value); last };
die "Unknown operator in conditional resolve", $/;
}
return 0 unless $res;
}
elsif (my $is = uc $context->get($self, 'IS'))
{
my $istrue = $val && 1;
if ($is eq 'TRUE')
{
return 0 unless $istrue;
}
else
{
warn "Conditional 'is' value was [$is], defaulting to 'FALSE'" . $/
if $is ne 'FALSE';
return 0 if $istrue;
}
}
return 1;
}
sub render
{
my $self = shift;
my ($context) = @_;
return 0 unless $self->should_render($context);
return 1 unless $self->conditional_passes($context);
return $self->iterate_over_children($context);
}
sub max_of
{
my $self = shift;
my ($context, $attr) = @_;
return 0 unless $self->conditional_passes($context);
return $self->SUPER::max_of($context, $attr);
}
sub total_of
{
my $self = shift;
my ($context, $attr) = @_;
return 0 unless $self->conditional_passes($context);
return $self->SUPER::total_of($context, $attr);
}
1;
__END__
=head1 NAME
PDF::Template::Container::Conditional
=head1 PURPOSE
To conditionally allow children to render
=head1 NODE NAME
CONDITIONAL
IF (an alias for CONDITIONAL)
=head1 INHERITANCE
PDF::Template::Container
=head1 ATTRIBUTES
=over 4
=item * NAME - Required. This is a parameter name, whose value will determine
if the conditional passed or fails. If NAME is not specified, the conditional
will consider to always fail.
=item * OP - defaults to == (numeric equality). If VALUE is specified, this will
be how NAME and VALUE are compared. OP can be any of the 6 numeric comparision
operators or the 6 string comparision operators.
=item * VALUE - if this is specified, OP will be checked. This is a standard
attribute, so if you want a parameter, prepend it with '$'.
=item * IS - If there is no VALUE attribute, this will be checked. IS can be
either 'FALSE' or 'TRUE'. The boolean of NAME will be compared and the
conditional will branch appropriately.
=back 4
=head1 CHILDREN
None
=head1 AFFECTS
Nothing
=head1 DEPENDENCIES
None
=head1 USAGE
<if name="__PAGE__" OP="!=" VALUE="__LAST_PAGE__">
... Children execute if the current page is not the last page ...
</if>
<if name="Param1" OP="eq" VALUE="$Param2">
... Children execute if Param1 is string-wise equals to Param2 ...
</if>
=head1 AUTHOR
Rob Kinyon (rkinyon@columbus.rr.com)
=head1 SEE ALSO
=cut