From c2eb18cb95332f700416d43394849d61d18cf00a Mon Sep 17 00:00:00 2001 From: Jiri Kozlovsky Date: Mon, 1 Aug 2016 05:47:05 +0200 Subject: [PATCH] Bug 17007: REST API: add route to get biblio --- Koha/REST/V1/Biblio.pm | 76 ++++++++++++++++++++++++++ api/v1/definitions/biblio.json | 65 ++++++++++++++++++++++ api/v1/definitions/index.json | 1 + api/v1/swagger.json | 32 +++++++++++ t/db_dependent/api/v1/biblios.t | 116 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 Koha/REST/V1/Biblio.pm create mode 100644 api/v1/definitions/biblio.json create mode 100644 t/db_dependent/api/v1/biblios.t diff --git a/Koha/REST/V1/Biblio.pm b/Koha/REST/V1/Biblio.pm new file mode 100644 index 0000000..a10a8fa --- /dev/null +++ b/Koha/REST/V1/Biblio.pm @@ -0,0 +1,76 @@ +package Koha::REST::V1::Biblio; + +# 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 strict; +use warnings; + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; +use Mojo::JSON; + +use C4::Auth qw( haspermission ); +use C4::Context; +use C4::Items qw( GetItem GetHiddenItemnumbers ); + +use Koha::Biblios; +use Koha::Items; + +sub get { + my ($c, $args, $cb) = @_; + + my $biblionumber = $c->param('biblionumber'); + my $biblio = Koha::Biblios->find($biblionumber); + + unless ($biblio) { + return $c->$cb({error => "Biblio not found"}, 404); + } + + my $items ||= Koha::Items->search( { biblionumber => $biblionumber }, { + columns => [qw/itemnumber/], + })->unblessed; + + my $user = $c->stash('koha.user'); + my $isStaff = haspermission($user->userid, {borrowers => 1}); + + # Hide the hidden items from all but staff + my $opachiddenitems = ! $isStaff + && ( C4::Context->preference('OpacHiddenItems') !~ /^\s*$/ ); + + if ($opachiddenitems) { + + my @hiddenitems = C4::Items::GetHiddenItemnumbers( @{$items} ); + + my @filteredItems = (); + + # Convert to a hash for quick searching + my %hiddenitems = map { $_ => 1 } @hiddenitems; + foreach my $itemnumber ( map { $_->{itemnumber} } @{$items} ) { + next if $hiddenitems{$itemnumber}; + push @filteredItems, { itemnumber => $itemnumber }; + } + + $items = \@filteredItems; + } + + $biblio = $biblio->unblessed; + $biblio->{items} = $items; + + return $c->$cb($biblio, 200); +} + +1; diff --git a/api/v1/definitions/biblio.json b/api/v1/definitions/biblio.json new file mode 100644 index 0000000..a3b35b7 --- /dev/null +++ b/api/v1/definitions/biblio.json @@ -0,0 +1,65 @@ +{ + "type": "object", + "properties": { + "biblionumber": { + "type": "string", + "description": "internal bibliographic record identifier" + }, + "frameworkcode": { + "type": "string", + "description": "foreign key from the biblio_framework table to identify which framework was used in cataloging this record" + }, + "author": { + "type": ["string", "null"], + "description": "statement of responsibility from MARC record (100$a in MARC21)" + }, + "title": { + "type": ["string", "null"], + "description": "title (without the subtitle) from the MARC record (245$a in MARC21)" + }, + "untitle": { + "type": ["string", "null"], + "description": "uniform title (without the subtitle) from the MARC record (240$a in MARC21)" + }, + "notes": { + "type": ["string", "null"], + "description": "values from the general notes field in the MARC record (500$a in MARC21) split by bar (|)" + }, + "serial": { + "type": ["string", "null"], + "description": "Boolean indicating whether biblio is for a serial" + }, + "seriestitle": { + "type": ["string", "null"], + "description": "Title for describing the series" + }, + "copyrightdate": { + "type": ["string", "null"], + "description": "publication or copyright date from the MARC record" + }, + "timestamp": { + "type": "string", + "description": "date and time this record was last touched" + }, + "datecreated": { + "type": "string", + "description": "the date this record was added to Koha" + }, + "abstract": { + "type": ["string", "null"], + "description": "summary from the MARC record (520$a in MARC21)" + }, + "items": { + "type": "array", + "items": { + "type": "object", + "properties": { + "itemnumber": { + "type": "string", + "description": "internal item identifier" + } + } + } + } + } +} diff --git a/api/v1/definitions/index.json b/api/v1/definitions/index.json index 3f69544..10efd36 100644 --- a/api/v1/definitions/index.json +++ b/api/v1/definitions/index.json @@ -2,5 +2,6 @@ "patron": { "$ref": "patron.json" }, "holds": { "$ref": "holds.json" }, "hold": { "$ref": "hold.json" }, + "biblio": { "$ref": "biblio.json" }, "error": { "$ref": "error.json" } } diff --git a/api/v1/swagger.json b/api/v1/swagger.json index b3f30f8..2bc6aa7 100644 --- a/api/v1/swagger.json +++ b/api/v1/swagger.json @@ -332,6 +332,31 @@ } } } + }, + "/biblios/{biblionumber}": { + "get": { + "operationId": "getBiblio", + "tags": ["biblios"], + "parameters": [ + { "$ref": "#/parameters/biblionumberPathParam" } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "responses": { + "200": { + "description": "An biblio", + "schema": { "$ref": "#/definitions/biblio" } + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { "$ref": "#/definitions/error" } + }, + "404": { + "description": "Biblio not found", + "schema": { "$ref": "#/definitions/error" } + } + } + } } }, "definitions": { @@ -351,6 +376,13 @@ "description": "Internal hold identifier", "required": true, "type": "integer" + }, + "biblionumberPathParam": { + "name": "biblionumber", + "in": "path", + "description": "Internal biblio identifier", + "required": true, + "type": "integer" } } } diff --git a/t/db_dependent/api/v1/biblios.t b/t/db_dependent/api/v1/biblios.t new file mode 100644 index 0000000..848fb7a --- /dev/null +++ b/t/db_dependent/api/v1/biblios.t @@ -0,0 +1,116 @@ +#!/usr/bin/env perl + +# Copyright 2016 Koha-Suomi +# +# 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 Test::More tests => 7; +use Test::Mojo; +use t::lib::TestBuilder; + +use C4::Auth; +use C4::Biblio; +use C4::Context; +use C4::Items; + +use Koha::Database; +use Koha::Patron; +use Koha::Items; + +my $builder = t::lib::TestBuilder->new(); + +my $dbh = C4::Context->dbh; +$dbh->{AutoCommit} = 0; +$dbh->{RaiseError} = 1; + +$ENV{REMOTE_ADDR} = '127.0.0.1'; +my $t = Test::Mojo->new('Koha::REST::V1'); + +my $categorycode = $builder->build({ source => 'Category' })->{ categorycode }; +my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; +my $borrower = $builder->build({ + source => 'Borrower', + value => { + branchcode => $branchcode, + categorycode => $categorycode, + flags => 16, + } +}); + +my $librarian = $builder->build({ + source => "Borrower", + value => { + categorycode => $categorycode, + branchcode => $branchcode, + flags => 4, + }, +}); + +my ($session) = create_session($borrower); + +my $biblio = $builder->build({ + source => 'Biblio' +}); +my $biblionumber = $biblio->{biblionumber}; +my $item1 = $builder->build({ + source => 'Item', + value => { + biblionumber => $biblionumber, + } +}); +my $item2 = $builder->build({ + source => 'Item', + value => { + biblionumber => $biblionumber, + } +}); +my $item1number = $item1->{itemnumber}; +my $item2number = $item2->{itemnumber}; + +my $nonExistentBiblionumber = -14362719; +my $tx = $t->ua->build_tx(GET => "/api/v1/biblios/$nonExistentBiblionumber"); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$t->request_ok($tx) + ->status_is(404); + +$tx = $t->ua->build_tx(GET => "/api/v1/biblios/$biblionumber"); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$t->request_ok($tx) + ->status_is(200) + ->json_is('/items/0/itemnumber' => $item1number) + ->json_is('/items/1/itemnumber' => $item2number) + ->json_is('/biblionumber' => $biblionumber); + +$dbh->rollback; + +sub create_session { + my (@borrowers) = @_; + + my @sessions; + foreach $borrower (@borrowers) { + my $session = C4::Auth::get_session(''); + $session->param('number', $borrower->{borrowernumber}); + $session->param('id', $borrower->{userid}); + $session->param('ip', '127.0.0.1'); + $session->param('lasttime', time()); + $session->flush; + push @sessions, $session; + } + + return @sessions; +} -- 2.1.4