#!/usr/bin/perl # Copyright 2007 LibLime # Copyright 2012 software.coop and MJ Ray # # 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, see . # use Modern::Perl; use CGI qw ( -utf8 ); use C4::Auth qw( check_api_auth ); use C4::Biblio qw( GetFrameworkCode ); use C4::Items; use XML::Simple; use Koha::Biblios; my $query = CGI->new; binmode STDOUT, ':encoding(UTF-8)'; my ( $status, $cookie, $sessionID ) = check_api_auth( $query, { editcatalogue => 'edit_catalogue' } ); unless ( $status eq "ok" ) { print $query->header( -type => 'text/xml', -status => '403 Forbidden' ); print XMLout( { auth_status => $status }, NoAttr => 1, RootName => 'response', XMLDecl => 1 ); exit 0; } # do initial validation my $path_info = $query->path_info(); my $biblionumber = undef; if ( $path_info =~ m!^/(\d+)$! ) { $biblionumber = $1; } else { print $query->header( -type => 'text/xml', -status => '400 Bad Request' ); } # are we retrieving, updating or deleting a bib? if ( $query->request_method eq "GET" ) { fetch_bib( $query, $biblionumber ); } elsif ( $query->request_method eq "POST" ) { update_bib( $query, $biblionumber ); } elsif ( $query->request_method eq "DELETE" ) { delete_bib( $query, $biblionumber ); } else { print $query->header( -type => 'text/xml', -status => '405 Method not allowed' ); print XMLout( { error => 'Method not allowed' }, NoAttr => 1, RootName => 'response', XMLDecl => 1 ); exit 0; } exit 0; sub fetch_bib { my ( $query, $biblionumber ) = @_; my $biblio = Koha::Biblios->find($biblionumber); my $record; my $exception; my $invalid_metadata = 0; if ( defined $biblio ) { eval { $record = $biblio->metadata_record( { embed_items => scalar $query->param('items') } ) }; if ($@) { $exception = $@; $exception->rethrow unless ( $exception->isa('Koha::Exceptions::Metadata::Invalid') ); $record = $biblio->metadata->record_strip_nonxml( { embed_items => scalar $query->param('items') } ); $invalid_metadata = 1; } print $query->header( -type => 'text/xml', -charset => 'utf-8', -invalid_metadata => $invalid_metadata ); print $record->as_xml_record(); } else { print $query->header( -type => 'text/xml', -status => '404 Not Found' ); } } sub update_bib { my $query = shift; my $biblionumber = shift; my $biblio = Koha::Biblios->find($biblionumber); my $old_record = $biblio->metadata; my $frameworkcode = $query->url_param('frameworkcode') // GetFrameworkCode($biblionumber); unless ( defined $old_record ) { print $query->header( -type => 'text/xml', -status => '404 Not Found' ); return; } my $result = {}; my $inxml = $query->param('POSTDATA'); print $query->header( -type => 'text/xml', -charset => 'utf-8' ); my $record = eval { MARC::Record::new_from_xml( $inxml, "UTF-8", C4::Context->preference('marcflavour') ) }; my $do_not_escape = 0; if ($@) { $result->{'status'} = "failed"; $result->{'error'} = $@; } else { my $fullrecord = $record->clone(); my ( $itemtag, $itemsubfield ) = C4::Biblio::GetMarcFromKohaField("items.itemnumber"); # delete any item tags foreach my $field ( $record->field($itemtag) ) { $record->delete_field($field); } if ( $query->url_param('items') ) { foreach my $field ( $fullrecord->field($itemtag) ) { my $one_item_record = $record->clone(); $one_item_record->add_fields($field); C4::Items::ModItemFromMarc( $one_item_record, $biblionumber, $field->subfield($itemsubfield) ); } } C4::Biblio::ModBiblio( $record, $biblionumber, $frameworkcode ); my $biblio = Koha::Biblios->find($biblionumber); my $new_record = $biblio->metadata_record( { embed_items => scalar $query->url_param('items') } ); $result->{'status'} = "ok"; $result->{'biblionumber'} = $biblionumber; my $xml = $new_record->as_xml_record(); $xml =~ s/<\?xml.*?\?>//i; $result->{'marcxml'} = $xml; $do_not_escape = 1; } print XMLout( $result, NoAttr => 1, RootName => 'response', XMLDecl => 1, NoEscape => $do_not_escape ); } sub delete_bib { my $query = shift; my $biblionumber = shift; my $error = C4::Biblio::DelBiblio($biblionumber); if ( defined $error ) { print $query->header( -type => 'text/xml', -status => '400 Bad request' ); print XMLout( { error => $error }, NoAttr => 1, RootName => 'response', XMLDecl => 1 ); exit 0; } print $query->header( -type => 'text/xml' ); print XMLout( { status => 'OK, biblio deleted' }, NoAttr => 1, RootName => 'response', XMLDecl => 1 ); }