1 # Copyright Tamil s.a.r.l. 2008-2015
2 # Copyright Biblibre 2008-2015
3 # Copyright The National Library of Finland, University of Helsinki 2016
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 package Koha::OAI::Server::Repository;
24 use HTTP::OAI::Repository qw( validate_request );
26 use base ("HTTP::OAI::Repository");
28 use Koha::OAI::Server::Identify;
29 use Koha::OAI::Server::ListSets;
30 use Koha::OAI::Server::ListMetadataFormats;
31 use Koha::OAI::Server::GetRecord;
32 use Koha::OAI::Server::ListRecords;
33 use Koha::OAI::Server::ListIdentifiers;
36 use CGI qw/:standard -oldstyle_urls/;
38 use C4::Biblio qw( GetMarcBiblio );
43 Koha::OAI::Server::Repository - Handles OAI-PMH requests for a Koha database.
47 use Koha::OAI::Server::Repository;
49 my $repository = Koha::OAI::Server::Repository->new();
53 This object extend HTTP::OAI::Repository object.
54 It accepts OAI-PMH HTTP requests and returns result.
56 This OAI-PMH server can operate in a simple mode and extended one.
58 In simple mode, repository configuration comes entirely from Koha system
59 preferences (OAI-PMH:archiveID and OAI-PMH:MaxCount) and the server returns
60 records in marcxml or dublin core format. Dublin core records are created from
61 koha marcxml records transformed with XSLT. Used XSL file is located in koha-
62 tmpl/intranet-tmpl/prog/en/xslt directory and chosen based on marcflavour,
63 respecively MARC21slim2OAIDC.xsl for MARC21 and MARC21slim2OAIDC.xsl for
66 In extended mode, it's possible to parameter other format than marcxml or
67 Dublin Core. A new syspref OAI-PMH:ConfFile specify a YAML configuration file
68 which list available metadata formats and XSL file used to create them from
69 marcxml records. If this syspref isn't set, Koha OAI server works in simple
70 mode. A configuration file koha-oai.conf can look like that:
76 metadataNamespace: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs
77 schema: http://veryspecial.tamil.fr/vs/format-pivot/1.1/vs.xsd
78 xsl_file: /usr/local/koha/xslt/vs.xsl
80 metadataPrefix: marc21
81 metadataNamespace: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim
82 schema: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd
85 metadataPrefix: marxml
86 metadataNamespace: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim
87 schema: http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd
90 metadataPrefix: oai_dc
91 metadataNamespace: http://www.openarchives.org/OAI/2.0/oai_dc/
92 schema: http://www.openarchives.org/OAI/2.0/oai_dc.xsd
93 xsl_file: /usr/local/koha/koha-tmpl/intranet-tmpl/xslt/UNIMARCslim2OAIDC.xsl
95 Note the 'include_items' parameter which is the only mean to return item-level info.
101 my ($class, %args) = @_;
102 my $self = $class->SUPER::new(%args);
104 $self->{ koha_identifier } = C4::Context->preference("OAI-PMH:archiveID");
105 $self->{ koha_max_count } = C4::Context->preference("OAI-PMH:MaxCount");
106 $self->{ koha_metadata_format } = ['oai_dc', 'marc21', 'marcxml'];
107 $self->{ xslt_engine } = Koha::XSLT::Base->new;
109 # Load configuration file if defined in OAI-PMH:ConfFile syspref
110 if ( my $file = C4::Context->preference("OAI-PMH:ConfFile") ) {
111 $self->{ conf } = YAML::XS::LoadFile( $file );
112 my @formats = keys %{ $self->{conf}->{format} };
113 $self->{ koha_metadata_format } = \@formats;
116 # OAI-PMH handles dates in UTC, so do that on the database level to avoid need for
118 my $sth = C4::Context->dbh->prepare('SELECT @@session.time_zone');
120 my ( $orig_tz ) = $sth->fetchrow();
121 $self->{ mysql_orig_tz } = $orig_tz;
122 C4::Context->dbh->prepare("SET time_zone='+00:00'")->execute();
124 # Check for grammatical errors in the request
125 my @errs = validate_request( CGI::Vars() );
127 # Is metadataPrefix supported by the repository?
128 my $mdp = param('metadataPrefix') || '';
129 if ( $mdp && !grep { $_ eq $mdp } @{$self->{ koha_metadata_format }} ) {
130 push @errs, HTTP::OAI::Error->new(
131 code => 'cannotDisseminateFormat',
132 message => "Dissemination as '$mdp' is not supported",
138 $response = HTTP::OAI::Response->new(
139 requestURL => self_url(),
144 my %attr = CGI::Vars();
145 my $verb = delete $attr{verb};
146 my $class = "Koha::OAI::Server::$verb";
147 $response = $class->new($self, %attr);
150 $response->set_handler( XML::SAX::Writer->new( Output => *STDOUT ) );
151 $response->xslt( "/opac-tmpl/xslt/OAI.xslt" );
162 # Reset time zone to the original value
163 C4::Context->dbh->prepare("SET time_zone='" . $self->{ mysql_orig_tz } . "'")->execute()
164 if $self->{ mysql_orig_tz };
168 sub get_biblio_marcxml {
169 my ($self, $biblionumber, $format) = @_;
171 if ( my $conf = $self->{conf} ) {
172 $with_items = $conf->{format}->{$format}->{include_items};
174 my $record = GetMarcBiblio({
175 biblionumber => $biblionumber,
176 embed_items => $with_items,
178 $record ? $record->as_xml_record() : undef;
183 my ( $self, $format ) = @_;
184 my $xsl_file = $self->{ conf }
185 ? $self->{ conf }->{ format }->{ $format }->{ xsl_file }
186 : ( C4::Context->config('intrahtdocs') .
188 C4::Context->preference('marcflavour') .
196 my ( $self, $format ) = @_;
198 if ( my $conf = $self->{ conf } ) {
199 return $conf->{ format }->{ $format }->{ include_items };