View | Details | Raw Unified | Return to bug 19196
Collapse All | Expand All

(-)a/Koha/REST/Plugin/Pagination.pm (-1 / +143 lines)
Line 0 Link Here
0
- 
1
package Koha::REST::Plugin::Pagination;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Plugin';
21
22
=head1 NAME
23
24
Koha::REST::Plugin::Pagination
25
26
=head1 API
27
28
=head2 Mojolicious::Plugin methods
29
30
=head3 register
31
32
=cut
33
34
sub register {
35
    my ( $self, $app ) = @_;
36
37
=head2 Helper methods
38
39
=head3 add_pagination_headers
40
41
    my $patrons = Koha::Patrons->search( ... );
42
    $c->add_pagination_headers({
43
        total  => $patrons->count,
44
        params => {
45
            page     => ...
46
            per_page => ...
47
            ...
48
        }
49
    });
50
51
Adds a Link header to the response message $c carries, following RFC5988, including
52
the following relation types: 'prev', 'next', 'first' and 'last'.
53
It also adds X-Total-Count, containing the total results count.
54
55
=cut
56
57
    $app->helper(
58
        'add_pagination_headers' => sub {
59
            my ( $c, $args ) = @_;
60
61
            my $total    = $args->{total};
62
            my $req_page = $args->{params}->{page};
63
            my $per_page = $args->{params}->{per_page};
64
65
            my $pages = int $total / $per_page;
66
            $pages++
67
                if $total % $per_page > 0;
68
69
            my @links;
70
71
            if ( $pages > 1 and $req_page > 1 ) {    # Previous exists?
72
                push @links,
73
                    _build_link(
74
                    $c,
75
                    {   page     => $req_page - 1,
76
                        per_page => $per_page,
77
                        rel      => 'prev',
78
                        params   => $args->{params}
79
                    }
80
                    );
81
            }
82
83
            if ( $pages > 1 and $req_page < $pages ) {    # Next exists?
84
                push @links,
85
                    _build_link(
86
                    $c,
87
                    {   page     => $req_page + 1,
88
                        per_page => $per_page,
89
                        rel      => 'next',
90
                        params   => $args->{params}
91
                    }
92
                    );
93
            }
94
95
            push @links,
96
                _build_link( $c,
97
                { page => 1, per_page => $per_page, rel => 'first', params => $args->{params} } );
98
            push @links,
99
                _build_link( $c,
100
                { page => $pages, per_page => $per_page, rel => 'last', params => $args->{params} } );
101
102
            # Add Link header
103
            $c->res->headers->add( 'Link' => join( ',', @links ) );
104
105
            # Add X-Total-Count header
106
            $c->res->headers->add( 'X-Total-Count' => $total );
107
            return $c;
108
        }
109
    );
110
}
111
112
=head2 Internal methods
113
114
=head3 _build_link
115
116
    my $link = _build_link( $c, { page => 1, per_page => 5, rel => 'prev' });
117
118
Returns a string, suitable for using in Link headers following RFC5988.
119
120
=cut
121
122
sub _build_link {
123
    my ( $c, $args ) = @_;
124
125
    my $params = $args->{params};
126
127
    $params->{page}     = $args->{page};
128
    $params->{per_page} = $args->{per_page};
129
130
    my $link = '<'
131
        . $c->req->url->clone->query(
132
            $params
133
        )->to_abs
134
        . '>; rel="'
135
        . $args->{rel} . '"';
136
137
    # TODO: Find a better solution for this horrible (but needed) fix
138
    $link =~ s|api/v1/app\.pl/||;
139
140
    return $link;
141
}
142
143
1;

Return to bug 19196