Fixed email address to gmail address
[p5sagit/Excel-Template.git] / lib / Excel / Template / Container / Conditional.pm
1 package Excel::Template::Container::Conditional;
2
3 #GGG Convert <conditional> to be a special case of <switch>?
4
5 use strict;
6
7 BEGIN {
8     use vars qw(@ISA);
9     @ISA = qw(Excel::Template::Container);
10
11     use Excel::Template::Container;
12 }
13
14 my %isOp = (
15     '='  => '==',
16     (map { $_ => $_ } ( '>', '<', '==', '!=', '>=', '<=' )),
17     (map { $_ => $_ } ( 'gt', 'lt', 'eq', 'ne', 'ge', 'le' )),
18 );
19
20 sub conditional_passes
21 {
22     my $self = shift;
23     my ($context) = @_;
24
25     my $name = $context->get($self, 'NAME');
26     return 0 unless $name =~ /\S/;
27
28     my $val = $context->param($name);
29     $val = @{$val} while UNIVERSAL::isa($val, 'ARRAY');
30     $val = ${$val} while UNIVERSAL::isa($val, 'SCALAR');
31
32     my $value = $context->get($self, 'VALUE');
33     if (defined $value)
34     {
35         my $op = $context->get($self, 'OP');
36         $op = defined $op && exists $isOp{$op}
37             ? $isOp{$op}
38             : '==';
39
40         # Force numerical context on both values;
41         $value *= 1;
42         $val *= 1;
43
44         my $res;
45         for ($op)
46         {
47             /^>$/  && do { $res = ($val > $value);  last };
48             /^<$/  && do { $res = ($val < $value);  last };
49             /^==$/ && do { $res = ($val == $value); last };
50             /^!=$/ && do { $res = ($val != $value); last };
51             /^>=$/ && do { $res = ($val >= $value); last };
52             /^<=$/ && do { $res = ($val <= $value); last };
53             /^gt$/ && do { $res = ($val gt $value); last };
54             /^lt$/ && do { $res = ($val lt $value); last };
55             /^eq$/ && do { $res = ($val eq $value); last };
56             /^ne$/ && do { $res = ($val ne $value); last };
57             /^ge$/ && do { $res = ($val ge $value); last };
58             /^le$/ && do { $res = ($val le $value); last };
59
60             die "Unknown operator in conditional resolve", $/;
61         }
62
63         return 0 unless $res;
64     }
65     elsif (my $is = uc $context->get($self, 'IS'))
66     {
67         my $istrue = $val && 1;
68         if ($is eq 'TRUE')
69         {
70             return 0 unless $istrue;
71         }
72         else
73         {
74             warn "Conditional 'is' value was [$is], defaulting to 'FALSE'" . $/
75                 if $is ne 'FALSE';
76
77             return 0 if $istrue;
78         }
79     }
80
81     return 1;
82 }
83
84 sub render
85 {
86     my $self = shift;
87     my ($context) = @_;
88
89     return 1 unless $self->conditional_passes($context);
90
91     return $self->iterate_over_children($context);
92 }
93
94 sub max_of
95 {
96     my $self = shift;
97     my ($context, $attr) = @_;
98
99     return 0 unless $self->conditional_passes($context);
100
101     return $self->SUPER::max_of($context, $attr);
102 }
103
104 sub total_of
105 {
106     my $self = shift;
107     my ($context, $attr) = @_;
108
109     return 0 unless $self->conditional_passes($context);
110
111     return $self->SUPER::total_of($context, $attr);
112 }
113
114 1;
115 __END__
116
117 =head1 NAME
118
119 Excel::Template::Container::Conditional - Excel::Template::Container::Conditional
120
121 =head1 PURPOSE
122
123 To provide conditional execution of children nodes
124
125 =head1 NODE NAME
126
127 IF
128
129 =head1 INHERITANCE
130
131 Excel::Template::Container
132
133 =head1 ATTRIBUTES
134
135 =over 4
136
137 =item * NAME
138
139 This is the name of the parameter to be testing. It is resolved like any other
140 parameter. 
141
142 =item * VALUE
143
144 If VALUE is set, then a comparison operation is done. The value of NAME is
145 compared to VALUE using the value of OP.
146
147 =item * OP
148
149 If VALUE is set, then this is checked. If it isn't present, then '==' (numeric
150 equality) is assumed. OP must be one of the numeric comparison operators or the
151 string comparison operators. All 6 of each kind is supported.
152
153 =item * IS
154
155 If VALUE is not set, then IS is checked. IS is allowed to be either "TRUE" or
156 "FALSE". The boolean value of NAME is checked against IS.
157
158 =back 4
159
160 =head1 CHILDREN
161
162 None
163
164 =head1 EFFECTS
165
166 None
167
168 =head1 DEPENDENCIES
169
170 None
171
172 =head1 USAGE
173
174   <if name="__ODD__" is="false">
175     ... Children here
176   </if>
177
178 In the above example, the children will be executed if the value of __ODD__
179 (which is set by the LOOP node) is false. So, for all even iterations.
180
181 =head1 AUTHOR
182
183 Rob Kinyon (rob.kinyon@gmail.com)
184
185 =head1 SEE ALSO
186
187 LOOP
188
189 =cut