Strict in 4 Dateien wieder deaktiviert.
[kivitendo-erp.git] / SL / Template / Plugin / MultiColumnIterator.pm
1 package SL::Template::Plugin::MultiColumnIterator;
2
3 #use strict;
4 use base 'Template::Plugin';
5 use Template::Constants;
6 use Template::Exception;
7 use Template::Iterator;
8 use SL::LXDebug;
9 use Data::Dumper;
10
11 our $AUTOLOAD;
12
13 sub new {
14     $main::lxdebug->enter_sub(); 
15     my $class   = shift;
16     my $context = shift;
17     my $data    = shift || [ ];
18     my $dim     = shift || 1;
19
20     $dim        = 1 if $dim < 1;
21
22     use vars qw(@ISA);
23     push @ISA, "Template::Iterator";
24
25     if (ref $data eq 'HASH') {
26         # map a hash into a list of { key => ???, value => ??? } hashes,
27         # one for each key, sorted by keys
28         $data = [ map { { key => $_, value => $data->{ $_ } } }
29                   sort keys %$data ];
30     }
31     elsif (UNIVERSAL::can($data, 'as_list')) {
32         $data = $data->as_list();
33     }
34     elsif (ref $data ne 'ARRAY') {
35         # coerce any non-list data into an array reference
36         $data  = [ $data ] ;
37     }
38
39     $main::lxdebug->leave_sub(); 
40
41     bless {
42         _DATA  => $data,
43         _ERROR => '',
44         _DIM   => $dim,
45     }, $class;
46 }
47
48
49 sub get_first {
50     $main::lxdebug->enter_sub(); 
51     my $self  = shift;
52     my $data  = $self->{ _DATA };
53     my $dim   = $self->{ _DIM  };
54
55     $self->{ _DATASET } = $self->{ _DATA };
56     my $size = int ((scalar @$data - 1) / $dim) + 1;
57     my $index = 0;
58     
59     return (undef, Template::Constants::STATUS_DONE) unless $size;
60
61     # initialise various counters, flags, etc.
62     @$self{ qw( SIZE MAX INDEX COUNT FIRST LAST ) } = ( $size, $size - 1, $index, 1, 1, $size > 1 ? 0 : 1, undef );
63     @$self{ qw( PREV ) } = ( undef );
64     $$self{ qw( NEXT ) } = [ @{ $self->{ _DATASET }  }[ map { $index + 1 + $_ * $size } 0 .. ($dim - 1) ] ];
65
66     $main::lxdebug->leave_sub(); 
67     return [ @{ $self->{ _DATASET } }[ map { $index + $_ * $size } 0 .. ($dim - 1) ] ];
68 }
69
70 sub get_next {
71     $main::lxdebug->enter_sub(); 
72     my $self = shift;
73     my ($max, $index) = @$self{ qw( MAX INDEX ) };
74     my $data = $self->{ _DATASET };
75     my $dim  = $self->{ _DIM  };
76     my $size = $self->{ SIZE  };
77
78     # warn about incorrect usage
79     unless (defined $index) {
80         my ($pack, $file, $line) = caller();
81         warn("iterator get_next() called before get_first() at $file line $line\n");
82         return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
83     }
84
85     # if there's still some data to go...
86     if ($index < $max) {
87         # update counters and flags
88         $index++;
89         @$self{ qw( INDEX COUNT FIRST LAST ) } = ( $index, $index + 1, 0, $index == $max ? 1 : 0 );
90         $$self{ qw( PREV ) } = [ @{ $self->{ _DATASET } }[ map { $index - 1 + $_ * $size } 0 .. ($dim - 1) ] ];
91         $$self{ qw( NEXT ) } = [ @{ $self->{ _DATASET } }[ map { $index + 1 + $_ * $size } 0 .. ($dim - 1) ] ];
92         $main::lxdebug->leave_sub(); 
93         return [ @{ $self->{ _DATASET } }[ map { $index + $_ * $size } 0 .. ($dim - 1) ] ];
94     }
95     else {
96         $main::lxdebug->leave_sub(); 
97         return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
98     }
99 }
100
101 sub get_all {
102     my $self = shift;
103     my ($max, $index, $dim, $size) = @$self{ qw( MAX INDEX _DIM SIZE) };
104     my (@data, $i);
105
106     # if there's still some data to go...
107     if ($index < $max) {
108         $index++;
109         @data = map do{ !($i = $_) || +[ @{ $self->{ _DATASET } }[ map { $i + $_ * $size } 0 .. ($dim - 1) ] ] }, $index .. $max;
110         # update counters and flags
111         @$self{ qw( INDEX COUNT FIRST LAST ) } = ( $max, $max + 1, 0, 1 );
112         $main::lxdebug->leave_sub();
113         return \@data;                                      ## RETURN ##
114     }
115     else {
116         $main::lxdebug->leave_sub();
117         return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
118     }
119 }
120
121 sub AUTOLOAD {
122     my $self = shift;
123     my $item = $AUTOLOAD;
124     $item =~ s/.*:://;
125     return if $item eq 'DESTROY';
126
127     # alias NUMBER to COUNT for backwards compatability
128     $item = 'COUNT' if $item =~ /NUMBER/i;
129
130     return $self->{ uc $item };
131 }
132
133 sub dump {
134     $main::lxdebug->enter_sub(); 
135     my $self = shift;
136     $main::lxdebug->leave_sub(); 
137     return join('',
138          "<pre>",
139          "  Data: ", Dumper($self->{ _DATA  }), "\n",
140          " Index: ", $self->{ INDEX  }, "\n",
141          "Number: ", $self->{ NUMBER }, "\n",
142          "   Max: ", $self->{ MAX    }, "\n",
143          "  Size: ", $self->{ SIZE   }, "\n",
144          " First: ", $self->{ FIRST  }, "\n",
145          "  Last: ", $self->{ LAST   }, "\n",
146          "\n",
147          "</pre>"
148      );
149 }
150
151 sub index {
152   $main::lxdebug->enter_sub(); 
153   my ($self) = @_;
154   $main::lxdebug->leave_sub(); 
155   return $self->{ INDEX };
156 }
157
158 sub number {
159   $main::lxdebug->enter_sub(); 
160   my ($self) = @_;
161   $main::lxdebug->leave_sub(); 
162   return $self->{ NUMBER };
163 }
164
165 sub count {
166   $main::lxdebug->enter_sub(); 
167   my ($self) = @_;
168   $main::lxdebug->leave_sub(); 
169   return $self->{ COUNT };
170 }
171 sub max {
172   $main::lxdebug->enter_sub(); 
173   my ($self) = @_;
174   $main::lxdebug->leave_sub(); 
175   return $self->{ MAX };
176 }
177
178 sub size {
179   $main::lxdebug->enter_sub(); 
180   my ($self) = @_;
181   $main::lxdebug->leave_sub(); 
182   return $self->{ SIZE };
183 }
184
185 sub first {
186   $main::lxdebug->enter_sub(); 
187   my ($self) = @_;
188   $main::lxdebug->leave_sub(); 
189   return $self->{ FIRST };
190 }
191
192 sub last {
193   $main::lxdebug->enter_sub(); 
194   my ($self) = @_;
195   $main::lxdebug->leave_sub(); 
196   return $self->{ LAST};
197 }
198
199 1;