File Coverage

blib/lib/Data/Pager.pm
Criterion Covered Total %
statement 88 90 97.7
branch 21 30 70.0
condition 13 17 76.4
subroutine 15 15 100.0
pod 5 6 83.3
total 142 158 89.8


line stmt bran cond sub pod time code
1             package Data::Pager;
2 1     1   30875 use strict;
  1         2  
  1         46  
3 1     1   6 use Carp;
  1         3  
  1         116  
4 1     1   1062 use POSIX qw(ceil);
  1         8491  
  1         37  
5 1     1   1365 use vars qw($VERSION);
  1         2  
  1         814  
6              
7             $VERSION = '0.01';
8              
9             sub new {
10 1     1 1 17 my $class = shift;
11 1         4 my $data = shift;
12 1         2 my $self = {};
13              
14 1 50       6 $class ne __PACKAGE__
15             and croak "class " . __PACKAGE__ . " constructor is not static";
16              
17 1         5 $self->{data}{fields} = $data;
18              
19 1         4 bless $self, $class;
20              
21 1         6 $self->__init($data);
22              
23 1         4 return $self;
24             }
25              
26             sub __init {
27 2192     2192   2681 my $self = shift;
28 2192   50     5608 my $data = shift || {};
29              
30 2192   100     7456 my $current = $data->{'current'} || 1;
31 2192   100     6436 my $offset = $data->{'offset'} || 10;
32 2192   50     10356 my $links = $data->{'perpage'} || 10;
33 2192   50     4937 my $limit = $data->{'limit'} || 0;
34              
35 2192         6402 $self->{'tmp'} = { links => $links };
36              
37 2192 50       8980 $links % 2 or $links += 1;
38              
39 2192         5089 my $middle = int( $links / 2 );
40 2192         4016 my %pager = ();
41 2192         4272 my %tmp = ();
42 2192         3059 my @pager = ();
43              
44             return undef
45 2192 50       5613 if $current * $offset - $offset + 1 > $limit;
46              
47 2192         4462 for my $i ( $current .. $current + $middle ) {
48 13152 50       39276 $pager{$i}++ if $i * $offset - $offset < $limit;
49             }
50 2192         4856 for my $i ( $current - $middle .. $current ) {
51 13152 100       38493 $pager{$i}++ if $i > 0;
52             }
53              
54 2192 100 100     11515 if ( scalar keys %pager < $links and $current < 5 ) {
55 9         25 while ( $middle++ < $links - 1 ) {
56 45 50       77 $middle > $limit
57             and last;
58 45 100       198 exists( $pager{$middle} )
59             or $pager{$middle}++;
60             }
61             }
62              
63 2192         12143 %tmp = %pager;
64 2192         6876 %pager = ();
65              
66 2192         9915 for my $pos ( sort { $a <=> $b } keys %tmp ) {
  58539         63608  
67 24101 100       44426 $pos == $current
68             and $pager{'current'} = $pos;
69 24101 100       107648 $pager{$pos} = {
    50          
70             'prev' => $pos - 1 ? $pos - 1 : undef,
71             'next' => $pos * $offset >= $limit ? undef: $pos + 1,
72             'from' => $offset * $pos - $offset,
73             'to' => $offset * $pos,
74             };
75 24101         43114 push @pager, $pos;
76             }
77              
78 2192         5772 $pager{'limit'} = $limit;
79 2192         3962 $pager{'list'} = \@pager;
80 2192         3839 $pager{'last'} = $pager[-1];
81 2192         6750 $pager{'first'} = $pager[0];
82 2192         3353 $pager{'start'} = 1;
83 2192         6017 $pager{'end'} = $self->final;
84 2192         4175 $pager{'offset'} = $offset;
85 2192         4503 $pager{'links'} = $self->{'tmp'}->{'links'};
86 2192   100     8679 $pager{'prev'} = $pager{ $pager{'current'} }->{'prev'} || undef;
87 2192   50     5984 $pager{'next'} = $pager{ $pager{'current'} }->{'next'} || undef;
88              
89 2192         27831 $self->{'data'} = \%pager;
90              
91             }
92              
93             sub list {
94 1     1   7 no strict 'refs';
  1         3  
  1         115  
95 1101     1101 1 5636 my $self = shift;
96             wantarray
97 0         0 ? @{ $self->{data}{list} }
  1101         4938  
98 1101 50       2688 : \@{ $self->{data}{list} };
99             }
100              
101             for my $method (qw(start first last set_current current prev next offset limit links))
102             {
103 1     1   6 no strict 'refs';
  1         1  
  1         275  
104             *$method = sub {
105 15145     15145   1047253 my $self = shift;
106 15145         18048 my $value = shift;
107 15145 100       32631 if ( $method eq 'set_current' ) {
108 2191 50       4845 if ( $value > 0 ) {
109 2191         4601 $self->{data}{current} = $value;
110 2191         5472 $self->__init( $self->{data} );
111 2191 50       4554 if ( $self->current eq $value ) {
112 2191         5790 return $self;
113             }
114             else {
115 0         0 return undef;
116             }
117             }
118             }
119 12954         55879 return $self->{data}{$method};
120             };
121             }
122              
123             sub from {
124 1091     1091 1 1690 my $self = shift;
125 1091         2839 $self->{'data'}->{ $self->current }{'from'};
126             }
127              
128             sub to {
129 1091     1091 1 4094 my $self = shift;
130 1091         2497 $self->{'data'}->{ $self->current }{'to'};
131             }
132              
133             sub final {
134 2194     2194 0 2974 my $self = shift;
135 1     1   7 no warnings;
  1         2  
  1         142  
136 2194         2856 return eval { ceil( $self->limit / $self->offset ) };
  2194         4223  
137             }
138              
139 1     1 1 2 sub end { shift->final }
140              
141             1;
142              
143             __END__