File Coverage

blib/lib/Data/Page.pm
Criterion Covered Total %
statement 87 87 100.0
branch 39 40 97.5
condition 24 24 100.0
subroutine 19 19 100.0
pod 14 14 100.0
total 183 184 99.4


line stmt bran cond sub pod time code
1             package Data::Page; # git description: v2.03-15-gf018461
2             # ABSTRACT: Help when paging through sets of results
3 4     4   119038 use Carp ();
  4         21  
  4         83  
4 4     4   16 use strict;
  4         8  
  4         73  
5 4     4   15 use warnings;
  4         6  
  4         111  
6 4     4   17 use base 'Class::Accessor::Chained::Fast';
  4         7  
  4         2057  
7             __PACKAGE__->mk_accessors(qw(total_entries entries_per_page current_page));
8              
9             our $VERSION = '2.04'; # TRIAL
10              
11             sub new {
12 77     77 1 34090 my $class = shift;
13 77         135 my $self = {};
14 77         122 bless( $self, $class );
15              
16 77         152 my ( $total_entries, $entries_per_page, $current_page ) = @_;
17 77   100     316 $self->total_entries( $total_entries || 0 );
18 77   100     740 $self->entries_per_page( $entries_per_page || 10 );
19 76   100     572 $self->current_page( $current_page || 1 );
20 76         545 return $self;
21             }
22              
23             sub entries_per_page {
24 187     187 1 1998 my $self = shift;
25 187 100       328 if (@_) {
26 186         218 my $ep = $_[0];
27 186 100 100     1185 Carp::croak('entries_per_page must be an integer')
      100        
28             if !defined($ep) or ref($ep) or int($ep) != $ep;
29 183 100       843 Carp::croak("Fewer than one entry per page!") if $ep < 1;
30 182         335 return $self->_entries_per_page_accessor(@_);
31             }
32 1         2 return $self->_entries_per_page_accessor();
33             }
34              
35             sub current_page {
36 337     337 1 8219 my $self = shift;
37 337 100       528 if (@_) {
38 191         300 my $cp = $_[0];
39 191 100 100     1103 Carp::croak('current_page must be an integer')
      100        
40             if !defined($cp) or ref($cp) or int($cp) != $cp;
41 187         314 my $fp = $self->first_page;
42 187 100       304 return $self->_current_page_accessor($fp) if $cp < $fp;
43 184         269 my $lp = $self->last_page;
44 184 100       301 return $self->_current_page_accessor($lp) if $cp > $lp;
45 181         294 return $self->_current_page_accessor(@_);
46             }
47 146         325 return $self->_current_page_accessor;
48             }
49              
50             sub total_entries {
51 117     117 1 5005 my $self = shift;
52 117 100       195 if (@_) {
53 116 100 100     769 Carp::croak('total_entries must be an integer')
      100        
54             if !defined($_[0]) or ref($_[0]) or int($_[0]) != $_[0];
55 113         259 return $self->_total_entries_accessor(@_);
56             }
57 1         4 return $self->_total_entries_accessor;
58             }
59              
60             sub entries_on_this_page {
61 72     72 1 29128 my $self = shift;
62              
63 72 100       164 if ( $self->_total_entries_accessor == 0 ) {
64 3         28 return 0;
65             } else {
66 69         445 return $self->last - $self->first + 1;
67             }
68             }
69              
70             sub first_page {
71 260     260 1 23313 my $self = shift;
72              
73 260         471 return 1;
74             }
75              
76             sub last_page {
77 569     569 1 1825 my $self = shift;
78              
79 569         933 my $pages = $self->_total_entries_accessor / $self->_entries_per_page_accessor;
80 569         5035 my $last_page;
81              
82 569 100       1142 if ( $pages == int $pages ) {
83 169         197 $last_page = $pages;
84             } else {
85 400         492 $last_page = 1 + int($pages);
86             }
87              
88 569 100       918 $last_page = 1 if $last_page < 1;
89 569         1133 return $last_page;
90             }
91              
92             sub first {
93 351     351 1 812 my $self = shift;
94              
95 351 100       715 if ( $self->_total_entries_accessor == 0 ) {
96 8         59 return 0;
97             } else {
98 343         1968 return ( ( $self->_current_page_accessor - 1 ) * $self->_entries_per_page_accessor ) + 1;
99             }
100             }
101              
102             sub last {
103 243     243 1 28541 my $self = shift;
104              
105 243 100       446 if ( $self->_current_page_accessor == $self->last_page ) {
106 123         1371 return $self->_total_entries_accessor;
107             } else {
108 120         230 return ( $self->_current_page_accessor * $self->_entries_per_page_accessor );
109             }
110             }
111              
112             sub previous_page {
113 71     71 1 30767 my $self = shift;
114              
115 71 100       158 if ( $self->_current_page_accessor > 1 ) {
116 30         215 return $self->_current_page_accessor - 1;
117             } else {
118 41         354 return undef;
119             }
120             }
121              
122             sub next_page {
123 71     71 1 30375 my $self = shift;
124              
125 71 100       157 $self->_current_page_accessor < $self->last_page ? $self->_current_page_accessor + 1 : undef;
126             }
127              
128             # This method would probably be better named 'select' or 'slice' or
129             # something, because it doesn't modify the array the way
130             # CORE::splice() does.
131             sub splice {
132 72     72 1 4209 my ( $self, $array ) = @_;
133 72 100       154 my $top = @$array > $self->last ? $self->last : @$array;
134 72 100       553 return () if $top == 0; # empty
135 68         114 return @{$array}[ $self->first - 1 .. $top - 1 ];
  68         777  
136             }
137              
138             sub skipped {
139 71     71 1 38881 my $self = shift;
140              
141 71         132 my $skipped = $self->first - 1;
142 71 100       724 return 0 if $skipped < 0;
143 68         217 return $skipped;
144             }
145              
146             sub change_entries_per_page {
147 70     70 1 132 my ( $self, $new_epp ) = @_;
148              
149 4     4   26194 use integer;
  4         52  
  4         19  
150 70 50       189 Carp::croak("Fewer than one entry per page!") if $new_epp < 1;
151 70         145 my $new_page = 1 + ( $self->first / $new_epp );
152 70         781 $self->entries_per_page($new_epp);
153 70         481 $self->current_page($new_page);
154             }
155              
156             1;
157              
158             __END__