342 lines
11 KiB
Perl
342 lines
11 KiB
Perl
package Koha::REST::V1::Authorities;
|
|
|
|
# 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 <https://www.gnu.org/licenses>.
|
|
|
|
use Modern::Perl;
|
|
|
|
use Mojo::Base 'Mojolicious::Controller';
|
|
|
|
use Koha::Authorities;
|
|
use C4::AuthoritiesMarc qw( DelAuthority AddAuthority FindDuplicateAuthority ModAuthority);
|
|
use C4::Matcher;
|
|
|
|
use List::MoreUtils qw( any );
|
|
use MARC::Record::MiJ;
|
|
|
|
use Try::Tiny qw( catch try );
|
|
|
|
=head1 API
|
|
|
|
=head2 Methods
|
|
|
|
=head3 get
|
|
|
|
Controller function that handles retrieving a single authority object
|
|
|
|
=cut
|
|
|
|
sub get {
|
|
my $c = shift->openapi->valid_input or return;
|
|
|
|
my $authority = Koha::Authorities->find( { authid => $c->param('authority_id') } );
|
|
|
|
return $c->render_resource_not_found("Authority record")
|
|
unless $authority;
|
|
|
|
return try {
|
|
|
|
if ( $c->req->headers->accept =~ m/application\/json/ ) {
|
|
return $c->render(
|
|
status => 200,
|
|
json => $c->objects->to_api($authority),
|
|
);
|
|
} else {
|
|
my $record = $authority->record;
|
|
|
|
$c->respond_to(
|
|
marcxml => {
|
|
status => 200,
|
|
format => 'marcxml',
|
|
text => $record->as_xml_record
|
|
},
|
|
mij => {
|
|
status => 200,
|
|
format => 'mij',
|
|
data => $record->to_mij
|
|
},
|
|
marc => {
|
|
status => 200,
|
|
format => 'marc',
|
|
text => $record->as_usmarc
|
|
},
|
|
txt => {
|
|
status => 200,
|
|
format => 'text/plain',
|
|
text => $record->as_formatted
|
|
},
|
|
any => {
|
|
status => 406,
|
|
openapi => [
|
|
"application/json",
|
|
"application/marcxml+xml",
|
|
"application/marc-in-json",
|
|
"application/marc",
|
|
"text/plain"
|
|
]
|
|
}
|
|
);
|
|
}
|
|
} catch {
|
|
$c->unhandled_exception($_);
|
|
};
|
|
}
|
|
|
|
=head3 delete
|
|
|
|
Controller function that handles deleting an authority object
|
|
|
|
=cut
|
|
|
|
sub delete {
|
|
my $c = shift->openapi->valid_input or return;
|
|
|
|
my $authority = Koha::Authorities->find( { authid => $c->param('authority_id') } );
|
|
|
|
return $c->render_resource_not_found("Authority record")
|
|
unless $authority;
|
|
|
|
return try {
|
|
DelAuthority( { authid => $authority->authid } );
|
|
|
|
return $c->render_resource_deleted;
|
|
} catch {
|
|
$c->unhandled_exception($_);
|
|
};
|
|
}
|
|
|
|
=head3 add
|
|
|
|
Controller function that handles creating an authority object
|
|
|
|
=cut
|
|
|
|
sub add {
|
|
my $c = shift->openapi->valid_input or return;
|
|
|
|
try {
|
|
my $headers = $c->req->headers;
|
|
my $overrides = $c->stash('koha.overrides');
|
|
|
|
my $flavour =
|
|
C4::Context->preference('marcflavour') eq 'UNIMARC'
|
|
? 'UNIMARCAUTH'
|
|
: 'MARC21';
|
|
|
|
my $record;
|
|
|
|
my $authtypecode = $headers->header('x-authority-type');
|
|
my $content_type = $headers->content_type;
|
|
|
|
if ( $content_type =~ m/application\/marcxml\+xml/ ) {
|
|
$record = MARC::Record->new_from_xml( $c->req->body, 'UTF-8', $flavour );
|
|
} elsif ( $content_type =~ m/application\/marc-in-json/ ) {
|
|
$record = MARC::Record->new_from_mij_structure( $c->req->json );
|
|
} elsif ( $content_type =~ m/application\/marc/ ) {
|
|
$record = MARC::Record->new_from_usmarc( $c->req->body );
|
|
} else {
|
|
return $c->render(
|
|
status => 406,
|
|
openapi => [
|
|
"application/marcxml+xml",
|
|
"application/marc-in-json",
|
|
"application/marc"
|
|
]
|
|
);
|
|
}
|
|
|
|
my $matcher_id = $headers->header('x-koha-matchrule');
|
|
my $matcher;
|
|
if ( defined $matcher_id && $matcher_id ne '' ) {
|
|
$matcher = C4::Matcher->fetch($matcher_id);
|
|
unless ($matcher) {
|
|
return $c->render(
|
|
status => 400,
|
|
openapi => {
|
|
error => "Matching rule $matcher_id not found",
|
|
error_code => 'matching_rule_not_found',
|
|
}
|
|
);
|
|
}
|
|
unless ( $matcher->record_type eq 'authority' ) {
|
|
return $c->render(
|
|
status => 400,
|
|
openapi => {
|
|
error => "Matching rule $matcher_id is not an authority matcher",
|
|
error_code => 'invalid_matching_rule_type',
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
unless ( $overrides->{any} || $overrides->{duplicate} ) {
|
|
if ($matcher) {
|
|
my @matches = $matcher->get_matches( $record, 10 );
|
|
if (@matches) {
|
|
my $first = $matches[0]->{record_id};
|
|
return $c->render(
|
|
status => 409,
|
|
openapi => {
|
|
error => "Duplicate record ($first)",
|
|
error_code => 'duplicate',
|
|
matches => [
|
|
map {
|
|
{
|
|
authid => $_->{record_id} + 0,
|
|
score => $_->{score} + 0,
|
|
}
|
|
} @matches
|
|
],
|
|
}
|
|
);
|
|
}
|
|
} else {
|
|
my ( $duplicateauthid, $duplicateauthvalue ) =
|
|
C4::AuthoritiesMarc::FindDuplicateAuthority( $record, $authtypecode );
|
|
|
|
return $c->render(
|
|
status => 409,
|
|
openapi => {
|
|
error => "Duplicate record ($duplicateauthid)",
|
|
error_code => 'duplicate',
|
|
}
|
|
) unless !$duplicateauthid;
|
|
}
|
|
}
|
|
|
|
my $authid = AddAuthority( $record, undef, $authtypecode );
|
|
|
|
$c->res->headers->location( $c->req->url->to_string . '/' . $authid );
|
|
$c->render(
|
|
status => 201,
|
|
openapi => q{},
|
|
);
|
|
} catch {
|
|
$c->unhandled_exception($_);
|
|
};
|
|
}
|
|
|
|
=head3 update
|
|
|
|
Controller function that handles modifying an authority object
|
|
|
|
=cut
|
|
|
|
sub update {
|
|
my $c = shift->openapi->valid_input or return;
|
|
|
|
my $authid = $c->param('authority_id');
|
|
my $authority = Koha::Authorities->find( { authid => $authid } );
|
|
|
|
return $c->render_resource_not_found("Authority record")
|
|
unless $authority;
|
|
|
|
try {
|
|
my $headers = $c->req->headers;
|
|
|
|
my $flavour =
|
|
C4::Context->preference('marcflavour') eq 'UNIMARC'
|
|
? 'UNIMARCAUTH'
|
|
: 'MARC21';
|
|
|
|
my $record;
|
|
my $authtypecode = $headers->header('x-authority-type') || $authority->authtypecode;
|
|
if ( $c->req->headers->content_type =~ m/application\/marcxml\+xml/ ) {
|
|
$record = MARC::Record->new_from_xml( $c->req->body, 'UTF-8', $flavour );
|
|
} elsif ( $c->req->headers->content_type =~ m/application\/marc-in-json/ ) {
|
|
$record = MARC::Record->new_from_mij_structure( $c->req->json );
|
|
} elsif ( $c->req->headers->content_type =~ m/application\/marc/ ) {
|
|
$record = MARC::Record->new_from_usmarc( $c->req->body );
|
|
} else {
|
|
return $c->render(
|
|
status => 406,
|
|
openapi => [
|
|
"application/json",
|
|
"application/marcxml+xml",
|
|
"application/marc-in-json",
|
|
"application/marc"
|
|
]
|
|
);
|
|
}
|
|
|
|
my $authid = ModAuthority( $authid, $record, $authtypecode );
|
|
|
|
$c->render(
|
|
status => 200,
|
|
openapi => { id => $authid }
|
|
);
|
|
} catch {
|
|
$c->unhandled_exception($_);
|
|
};
|
|
}
|
|
|
|
=head3 list
|
|
|
|
Controller function that handles retrieving a list of authorities
|
|
|
|
=cut
|
|
|
|
sub list {
|
|
my $c = shift->openapi->valid_input or return;
|
|
|
|
my $authorities = $c->objects->search_rs( Koha::Authorities->new );
|
|
|
|
return try {
|
|
|
|
if ( $c->req->headers->accept =~ m/application\/json(;.*)?$/ ) {
|
|
return $c->render(
|
|
status => 200,
|
|
json => $c->objects->to_api($authorities),
|
|
);
|
|
} elsif ( $c->req->headers->accept =~ m/application\/marcxml\+xml(;.*)?$/ ) {
|
|
$c->res->headers->add( 'Content-Type', 'application/marcxml+xml' );
|
|
return $c->render(
|
|
status => 200,
|
|
text => $authorities->print_collection('marcxml')
|
|
);
|
|
} elsif ( $c->req->headers->accept =~ m/application\/marc-in-json(;.*)?$/ ) {
|
|
$c->res->headers->add( 'Content-Type', 'application/marc-in-json' );
|
|
return $c->render(
|
|
status => 200,
|
|
data => $authorities->print_collection('mij')
|
|
);
|
|
} elsif ( $c->req->headers->accept =~ m/application\/marc(;.*)?$/ ) {
|
|
$c->res->headers->add( 'Content-Type', 'application/marc' );
|
|
return $c->render(
|
|
status => 200,
|
|
text => $authorities->print_collection('marc')
|
|
);
|
|
} elsif ( $c->req->headers->accept =~ m/text\/plain(;.*)?$/ ) {
|
|
return $c->render(
|
|
status => 200,
|
|
text => $authorities->print_collection('txt')
|
|
);
|
|
} else {
|
|
return $c->render(
|
|
status => 406,
|
|
openapi => [
|
|
"application/json", "application/marcxml+xml",
|
|
"application/marc-in-json", "application/marc",
|
|
"text/plain"
|
|
]
|
|
);
|
|
}
|
|
} catch {
|
|
$c->unhandled_exception($_);
|
|
};
|
|
}
|
|
|
|
1;
|