+++ /dev/null
-package SL::Template::Plugin::MultiColumnIterator;
-
-use base 'Template::Plugin';
-use Template::Constants;
-use Template::Exception;
-use Template::Iterator;
-use SL::LXDebug;
-use Data::Dumper;
-
-use strict;
-
-our $AUTOLOAD;
-
-sub new {
- $main::lxdebug->enter_sub();
- my $class = shift;
- my $context = shift;
- my $data = shift || [ ];
- my $dim = shift || 1;
-
- $dim = 1 if $dim < 1;
-
- use vars qw(@ISA);
- push @ISA, "Template::Iterator";
-
- if (ref $data eq 'HASH') {
- # map a hash into a list of { key => ???, value => ??? } hashes,
- # one for each key, sorted by keys
- $data = [ map { { key => $_, value => $data->{ $_ } } }
- sort keys %$data ];
- }
- elsif (UNIVERSAL::can($data, 'as_list')) {
- $data = $data->as_list();
- }
- elsif (ref $data ne 'ARRAY') {
- # coerce any non-list data into an array reference
- $data = [ $data ] ;
- }
-
- $main::lxdebug->leave_sub();
-
- bless {
- _DATA => $data,
- _ERROR => '',
- _DIM => $dim,
- }, $class;
-}
-
-
-sub get_first {
- $main::lxdebug->enter_sub();
- my $self = shift;
- my $data = $self->{ _DATA };
- my $dim = $self->{ _DIM };
-
- $self->{ _DATASET } = $self->{ _DATA };
- my $size = int ((scalar @$data - 1) / $dim) + 1;
- my $index = 0;
-
- return (undef, Template::Constants::STATUS_DONE) unless $size;
-
- # initialise various counters, flags, etc.
- @$self{ qw( SIZE MAX INDEX COUNT FIRST LAST ) } = ( $size, $size - 1, $index, 1, 1, $size > 1 ? 0 : 1, undef );
- @$self{ qw( PREV ) } = ( undef );
- $$self{ qw( NEXT ) } = [ @{ $self->{ _DATASET } }[ map { $index + 1 + $_ * $size } 0 .. ($dim - 1) ] ];
-
- $main::lxdebug->leave_sub();
- return [ @{ $self->{ _DATASET } }[ map { $index + $_ * $size } 0 .. ($dim - 1) ] ];
-}
-
-sub get_next {
- $main::lxdebug->enter_sub();
- my $self = shift;
- my ($max, $index) = @$self{ qw( MAX INDEX ) };
- my $data = $self->{ _DATASET };
- my $dim = $self->{ _DIM };
- my $size = $self->{ SIZE };
-
- # warn about incorrect usage
- unless (defined $index) {
- my ($pack, $file, $line) = caller();
- warn("iterator get_next() called before get_first() at $file line $line\n");
- return (undef, Template::Constants::STATUS_DONE); ## RETURN ##
- }
-
- # if there's still some data to go...
- if ($index < $max) {
- # update counters and flags
- $index++;
- @$self{ qw( INDEX COUNT FIRST LAST ) } = ( $index, $index + 1, 0, $index == $max ? 1 : 0 );
- $$self{ qw( PREV ) } = [ @{ $self->{ _DATASET } }[ map { $index - 1 + $_ * $size } 0 .. ($dim - 1) ] ];
- $$self{ qw( NEXT ) } = [ @{ $self->{ _DATASET } }[ map { $index + 1 + $_ * $size } 0 .. ($dim - 1) ] ];
- $main::lxdebug->leave_sub();
- return [ @{ $self->{ _DATASET } }[ map { $index + $_ * $size } 0 .. ($dim - 1) ] ];
- }
- else {
- $main::lxdebug->leave_sub();
- return (undef, Template::Constants::STATUS_DONE); ## RETURN ##
- }
-}
-
-sub get_all {
- my $self = shift;
- my ($max, $index, $dim, $size) = @$self{ qw( MAX INDEX _DIM SIZE) };
- my (@data, $i);
-
- # if there's still some data to go...
- if ($index < $max) {
- $index++;
- @data = map do{ !($i = $_) || +[ @{ $self->{ _DATASET } }[ map { $i + $_ * $size } 0 .. ($dim - 1) ] ] }, $index .. $max;
- # update counters and flags
- @$self{ qw( INDEX COUNT FIRST LAST ) } = ( $max, $max + 1, 0, 1 );
- $main::lxdebug->leave_sub();
- return \@data; ## RETURN ##
- }
- else {
- $main::lxdebug->leave_sub();
- return (undef, Template::Constants::STATUS_DONE); ## RETURN ##
- }
-}
-
-sub AUTOLOAD {
- my $self = shift;
- my $item = $AUTOLOAD;
- $item =~ s/.*:://;
- return if $item eq 'DESTROY';
-
- # alias NUMBER to COUNT for backwards compatability
- $item = 'COUNT' if $item =~ /NUMBER/i;
-
- return $self->{ uc $item };
-}
-
-sub dump {
- $main::lxdebug->enter_sub();
- my $self = shift;
- $main::lxdebug->leave_sub();
- return join('',
- "<pre>",
- " Data: ", Dumper($self->{ _DATA }), "\n",
- " Index: ", $self->{ INDEX }, "\n",
- "Number: ", $self->{ NUMBER }, "\n",
- " Max: ", $self->{ MAX }, "\n",
- " Size: ", $self->{ SIZE }, "\n",
- " First: ", $self->{ FIRST }, "\n",
- " Last: ", $self->{ LAST }, "\n",
- "\n",
- "</pre>"
- );
-}
-
-sub index {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ INDEX };
-}
-
-sub number {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ NUMBER };
-}
-
-sub count {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ COUNT };
-}
-sub max {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ MAX };
-}
-
-sub size {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ SIZE };
-}
-
-sub first {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ FIRST };
-}
-
-sub last {
- $main::lxdebug->enter_sub();
- my ($self) = @_;
- $main::lxdebug->leave_sub();
- return $self->{ LAST};
-}
-
-1;