From 4c993ca6b58b8e83aeaeac0fdbd614a8b4a39677 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Tue, 29 Aug 2017 16:52:48 -0300 Subject: [PATCH] Bug 19196: Add Koha::REST::Plugin::Pagination This patch introduces a Mojolicious plugin to be used on the REST api. It adds two helper methods: total_count_header ================== When used, it adds an _X-Total-Count_ header with the value it got passed like this: my $patrons = Koha::Patrons->search; my $count = $patrons->count; $c->total_count_header({ total_count => $count }); => Response contains X-Total-Count: $count links_header ============ When used, it adds a _Link_ header to the reponse with the calculated values for pagination, like this: my $patrons = Koha::Patrons->search; my $count = $patrons->count; $c->links_header({ total => $count, page => 2, per_page => 2 }); To test: - Run: $ sudo koha-shell kohadev k$ cd kohaclone k$ prove t/Koha/REST/Plugin/Pagination.t => SUCCESS: Tests pass! - Sign off :-D Sponsored-by: ByWater solutions Sponsored-by: Camden County --- Koha/REST/Plugin/Pagination.pm | 90 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Koha/REST/Plugin/Pagination.pm diff --git a/Koha/REST/Plugin/Pagination.pm b/Koha/REST/Plugin/Pagination.pm new file mode 100644 index 0000000000..54a0954d2f --- /dev/null +++ b/Koha/REST/Plugin/Pagination.pm @@ -0,0 +1,90 @@ +package Koha::REST::Plugin::Pagination; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Plugin'; + +sub register { + my ( $self, $app ) = @_; + + $app->helper( + 'links_header' => sub { + my ( $c, $params ) = @_; + + my $total = $params->{total}; + my $page = $params->{page}; + my $per_page = $params->{per_page}; + + my $pages = int $total / $per_page; + $pages++ + if $total % $per_page > 0; + + + my @links; + + if ( $pages > 1 and $page > 1 ) { # Previous exists? + push @links, + _build_link( $c, { page => $page - 1, per_page => $per_page, rel => 'prev' } ); + } + + if ( $pages > 1 and $page < $pages ) { # Next exists? + push @links, + _build_link( $c, { page => $page + 1, per_page => $per_page, rel => 'next' } ); + } + + push @links, _build_link( $c, { page => 1, per_page => $per_page, rel => 'first' } ); + push @links, _build_link( $c, { page => $pages, per_page => $per_page, rel => 'last' } ); + + $c->res->headers->add( 'Link' => join( ',', @links ) ); + + return $c; + } + ); + + $app->helper( + 'total_count_header' => sub { + my ( $c, $params ) = @_; + my $total_count = $params->{total_count}; + + $c->res->headers->add( 'X-Total-Count' => $total_count ) + if $total_count; + + return $c; + } + ); +} + +sub _build_link { + my ( $c, $params ) = @_; + + my $link = '<' + . $c->req->url->clone->query( + [ 'per_page' => $params->{per_page}, + 'page' => $params->{page} + ] + )->to_abs + . '>; rel="' + . $params->{rel} . '"'; + + # TODO: Find a better solution for this horrible (but needed) fix + $link =~ s|api\/v1\/app\.pl\/||; + + return $link; +} + +1; -- 2.14.1