Commit | Line | Data |
d0eafc11 |
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 (rkinyon@columbus.rr.com) |
184 | |
185 | =head1 SEE ALSO |
186 | |
187 | LOOP |
188 | |
189 | =cut |