From 8ee2d7149baa58ea225cb40e0f95030ee21f1081 Mon Sep 17 00:00:00 2001 From: "Jannis M. Hoffmann" Date: Mon, 13 Mar 2023 21:34:03 +0100 Subject: Split up Helper plugin and added Views instead --- lib/JWebmail/Plugin/Paginate.pm | 145 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 lib/JWebmail/Plugin/Paginate.pm (limited to 'lib/JWebmail/Plugin/Paginate.pm') diff --git a/lib/JWebmail/Plugin/Paginate.pm b/lib/JWebmail/Plugin/Paginate.pm new file mode 100644 index 0000000..1a48ed3 --- /dev/null +++ b/lib/JWebmail/Plugin/Paginate.pm @@ -0,0 +1,145 @@ +package JWebmail::Plugin::Paginate; + +use Mojo::Base Mojolicious::Plugin; + +use List::Util qw(any max); +use POSIX 'ceil'; + + +sub _clamp { + my ($x, $y, $z) = @_; + + die '!($x <= $z)' unless $x <= $z; + + if ($x <= $y && $y <= $z) { + return $y; + } + + return $x if ($y < $x); + return $z if ($z < $y); +} + +sub _paginate { + my %args = @_; + + my $first_item = $args{first_item}; + my $page_size = $args{page_size}; + my $total_items = $args{total_items}; + + my $current_page = ceil($first_item/$page_size); + my $total_pages = ceil($total_items/$page_size); + + my $page = sub { + my $page_ = shift; + return [0, 0] unless $total_items; + $page_ = _clamp(0, $page_, $total_pages-1); + [_clamp(0, $page_*$page_size, $total_items-1), _clamp(0, ($page_+1)*$page_size, $total_items)] + }; + + my $ret = { + total_items => $total_items, + page_size => $page_size, + + total_pages => $total_pages, + current_page => $current_page, + + first_page => $page->(0), + prev_page => $page->($current_page-1), + this_page => $page->($current_page), + next_page => $page->($current_page+1), + last_page => $page->($total_pages-1), + }; + + if ($total_items) { + $ret->{first_item} = $first_item; + $ret->{last_item} = _clamp($first_item, $first_item+$page_size-1, $total_items-1); + } + + return $ret; +} + +sub paginate { + my $c = shift; + my ($count) = @_; + + my $v = $c->validation; + my $start = $v->optional('start')->num(0, undef)->param // 0; + my $psize = $v->optional('page_size')->num(1, undef)->param // 50; + + $start = _clamp(0, $start, max($count-1, 0)); + my $end = _clamp($start, $start+$psize, max($count, 0)); + + $c->stash(pgn => _paginate( + first_item => int($start/$psize)*$psize, + page_size => $psize, + total_items => $count, + )); + + return $start, $end; +} + + +sub register { + my ($self, $app, $conf) = @_; + $conf //= {}; + + $app->helper(paginate => \&paginate); +} + + +1 + +__END__ + +=encoding utf-8 + +=head1 NAME + +JWebmail::Plugin::Paginate + +=head1 SYNOPSIS + + sub my_route { + my ($c) = @_; + + $c->stash($c->paginate(1234)); + } + +=head1 DESCRIPTION + +L provides useful helper functions and validator cheks and filter for +L and various templates. + +=head1 HELPERS + +=head2 paginate + +A helper for calculating page bounds. + +Takes the total number of items as argument. + +Reads in 'start' and 'page_size' query arguments. +start is 0 based. + +Returns the calculated start and end points as 0 based inclusive range. + +Sets the stash values (all 1 based inclusive): + + first_item + last_item + total_items + page_size + total_pages + current_page + first_page + prev_page + next_page + last_page + +=head1 SEE ALSO + +L + +=head1 NOTICE + +This package is part of JWebmail. -- cgit v1.2.3