Bug 24909: Add unprivileged route to get a bibliographic record
[srvgit] / Koha / REST / V1 / Biblios.pm
1 package Koha::REST::V1::Biblios;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Mojo::Base 'Mojolicious::Controller';
21
22 use Koha::Biblios;
23 use Koha::RecordProcessor;
24 use C4::Biblio qw(DelBiblio);
25
26 use MARC::Record::MiJ;
27
28 use Try::Tiny;
29
30 =head1 API
31
32 =head2 Methods
33
34 =head3 get
35
36 Controller function that handles retrieving a single biblio object
37
38 =cut
39
40 sub get {
41     my $c = shift->openapi->valid_input or return;
42
43     my $attributes;
44     $attributes = { prefetch => [ 'metadata' ] } # don't prefetch metadata if not needed
45         unless $c->req->headers->accept =~ m/application\/json/;
46
47     my $biblio = Koha::Biblios->find( { biblionumber => $c->validation->param('biblio_id') }, $attributes );
48
49     unless ( $biblio ) {
50         return $c->render(
51             status  => 404,
52             openapi => {
53                 error => "Object not found."
54             }
55         );
56     }
57
58     return try {
59
60         if ( $c->req->headers->accept =~ m/application\/json/ ) {
61             return $c->render(
62                 status => 200,
63                 json   => $biblio->to_api
64             );
65         }
66         else {
67             my $record = $biblio->metadata->record;
68
69             $c->respond_to(
70                 marcxml => {
71                     status => 200,
72                     format => 'marcxml',
73                     text   => $record->as_xml_record
74                 },
75                 mij => {
76                     status => 200,
77                     format => 'mij',
78                     text   => $record->to_mij
79                 },
80                 marc => {
81                     status => 200,
82                     format => 'marc',
83                     text   => $record->as_usmarc
84                 },
85                 any => {
86                     status  => 406,
87                     openapi => [
88                         "application/json",
89                         "application/marcxml+xml",
90                         "application/marc-in-json",
91                         "application/marc"
92                     ]
93                 }
94             );
95         }
96     }
97     catch {
98         return $c->render(
99             status  => 500,
100             openapi => { error => "Something went wrong, check the logs ($_)" }
101         );
102     };
103 }
104
105 =head3 delete
106
107 Controller function that handles deleting a biblio object
108
109 =cut
110
111 sub delete {
112     my $c = shift->openapi->valid_input or return;
113
114     my $biblio = Koha::Biblios->find( $c->validation->param('biblio_id') );
115
116     if ( not defined $biblio ) {
117         return $c->render(
118             status  => 404,
119             openapi => { error => "Object not found" }
120         );
121     }
122
123     return try {
124         my $error = DelBiblio( $biblio->id );
125
126         if ($error) {
127             return $c->render(
128                 status  => 409,
129                 openapi => { error => $error }
130             );
131         }
132         else {
133             return $c->render( status => 204, openapi => "" );
134         }
135     }
136     catch {
137         if ( $_->isa('DBIx::Class::Exception') ) {
138             return $c->render(
139                 status  => 500,
140                 openapi => { error => $_->{msg} }
141             );
142         }
143         else {
144             return $c->render(
145                 status  => 500,
146                 openapi => { error => "Something went wrong, check the logs." }
147             );
148         }
149     };
150 }
151
152 =head3 get_public
153
154 Controller function that handles retrieving a single biblio object
155
156 =cut
157
158 sub get_public {
159     my $c = shift->openapi->valid_input or return;
160
161     my $biblio = Koha::Biblios->find(
162         { biblionumber => $c->validation->param('biblio_id') },
163         { prefetch     => ['metadata'] } );
164
165     unless ($biblio) {
166         return $c->render(
167             status  => 404,
168             openapi => {
169                 error => "Object not found."
170             }
171         );
172     }
173
174     return try {
175
176         my $record = $biblio->metadata->record;
177
178         my $opachiddenitems_rules = C4::Context->yaml_preference('OpacHiddenItems');
179         my $patron = $c->stash('koha.user');
180
181         # Check if the biblio should be hidden for unprivileged access
182         # unless there's a logged in user, and there's an exception for it's
183         # category
184         unless ( $patron and $patron->category->override_hidden_items ) {
185             if ( $biblio->hidden_in_opac({ rules => $opachiddenitems_rules }) )
186             {
187                 return $c->render(
188                     status  => 404,
189                     openapi => {
190                         error => "Object not found."
191                     }
192                 );
193             }
194         }
195
196         my $marcflavour = C4::Context->preference("marcflavour");
197
198         my $record_processor = Koha::RecordProcessor->new({
199             filters => 'ViewPolicy',
200             options => {
201                 interface => 'opac',
202                 frameworkcode => $biblio->frameworkcode
203             }
204         });
205         # Apply framework's filtering to MARC::Record object
206         $record_processor->process($record);
207
208         $c->respond_to(
209             marcxml => {
210                 status => 200,
211                 format => 'marcxml',
212                 text   => $record->as_xml_record
213             },
214             mij => {
215                 status => 200,
216                 format => 'mij',
217                 text   => $record->to_mij
218             },
219             marc => {
220                 status => 200,
221                 format => 'marc',
222                 text   => $record->as_usmarc
223             },
224             txt => {
225                 status => 200,
226                 format => 'text/plain',
227                 text   => $record->as_formatted
228             },
229             any => {
230                 status  => 406,
231                 openapi => [
232                     "application/marcxml+xml",
233                     "application/marc-in-json",
234                     "application/marc",
235                     "text/plain"
236                 ]
237             }
238         );
239     }
240     catch {
241         return $c->render(
242             status  => 500,
243             openapi => { error => "Something went wrong, check the logs ($_)" }
244         );
245     };
246 }
247
248 1;