X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FHeading.pm;h=5dfd0fadb0d903184ca519682ee750fb16ff932a;hb=refs%2Fheads%2Fkoha_ffzg;hp=ae1a0d03f7fc7459a7f216f93d2ddec5566e1691;hpb=c9ba8c899d854d4190df783f3f1aec2989d2cb10;p=koha.git diff --git a/C4/Heading.pm b/C4/Heading.pm index ae1a0d03f7..5dfd0fadb0 100644 --- a/C4/Heading.pm +++ b/C4/Heading.pm @@ -1,31 +1,30 @@ package C4::Heading; # Copyright (C) 2008 LibLime -# +# # 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 2 of the License, or (at your option) any later -# version. +# 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. +# 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. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; -use strict; -#use warnings; FIXME - Bug 2505 use MARC::Record; use MARC::Field; use C4::Context; -use C4::Heading::MARC21; -use C4::Search; +use Module::Load; +use Carp; -our $VERSION = 3.00; =head1 NAME @@ -33,12 +32,12 @@ C4::Heading =head1 SYNOPSIS -use C4::Heading; -my $heading = C4::Heading->new_from_bib_field($field); -my $thesaurus = $heading->thesaurus(); -my $type = $heading->type(); -my $display_heading = $heading->display(); -my $search_string = $heading->search_string(); + use C4::Heading; + my $heading = C4::Heading->new_from_bib_field($field, $frameworkcode); + my $thesaurus = $heading->thesaurus(); + my $type = $heading->type(); + my $display_heading = $heading->display_form(); + my $search_form = $heading->search_form(); =head1 DESCRIPTION @@ -49,11 +48,7 @@ headings found in bibliographic and authority records. =head2 new_from_bib_field -=over 4 - -my $heading = C4::Heading->new_from_bib_field($field[, $marc_flavour]); - -=back + my $heading = C4::Heading->new_from_bib_field($field, $frameworkcode, [, $marc_flavour]); Given a C object containing a heading from a bib record, create a C object. @@ -68,31 +63,57 @@ is returned. =cut sub new_from_bib_field { - my $class = shift; - my $field = shift; - my $marcflavour = @_ ? shift : C4::Context->preference('marcflavour'); + my $class = shift; + my $field = shift; + my $frameworkcode = shift; + my $marcflavour = @_ ? shift : C4::Context->preference('marcflavour'); my $marc_handler = _marc_format_handler($marcflavour); my $tag = $field->tag(); - return unless $marc_handler->valid_bib_heading_tag($tag); + return unless $marc_handler->valid_bib_heading_tag( $tag, $frameworkcode ); my $self = {}; - - ($self->{'auth_type'}, $self->{'subject_added_entry'}, $self->{'series_added_entry'}, $self->{'main_entry'}, - $self->{'thesaurus'}, $self->{'search_form'}, $self->{'display_form'}) = - $marc_handler->parse_heading($field); + + $self->{'field'} = $field; + ( + $self->{'auth_type'}, $self->{'thesaurus'}, + $self->{'search_form'}, $self->{'display_form'}, + $self->{'match_type'} + ) = $marc_handler->parse_heading($field); bless $self, $class; return $self; } -=head2 display_form +=head2 auth_type + + my $auth_type = $heading->auth_type(); + +Return the auth_type of the heading. + +=cut + +sub auth_type { + my $self = shift; + return $self->{'auth_type'}; +} -=over 4 +=head2 field -my $display = $heading->display_form(); + my $field = $heading->field(); -=back +Return the MARC::Field the heading is based on. + +=cut + +sub field { + my $self = shift; + return $self->{'field'}; +} + +=head2 display_form + + my $display = $heading->display_form(); Return the "canonical" display form of the heading. @@ -103,34 +124,39 @@ sub display_form { return $self->{'display_form'}; } -=head2 authorities +=head2 search_form -=over 4 + my $search_form = $heading->search_form(); -my $authorities = $heading->authorities; +Return the "canonical" search form of the heading. -=back +=cut + +sub search_form { + my $self = shift; + return $self->{'search_form'}; +} + +=head2 authorities + + my $authorities = $heading->authorities([$skipmetadata]); Return a list of authority records for this -heading. +heading. If passed a true value for $skipmetadata, +SearchAuthorities will return only authids. =cut sub authorities { - my $self = shift; - my $query = qq(Match-heading,ext="$self->{'search_form'}"); - $query .= $self->_query_limiters(); - my ($error, $results, $total_hits) = SimpleSearch( $query, undef, undef, [ "authorityserver" ] ); + my $self = shift; + my $skipmetadata = shift; + my ( $results, $total ) = _search( $self, 'match-heading', $skipmetadata ); return $results; } =head2 preferred_authorities -=over 4 - -my $preferred_authorities = $heading->preferred_authorities; - -=back + my $preferred_authorities = $heading->preferred_authorities; Return a list of authority records for headings that are a preferred form of the heading. @@ -139,33 +165,75 @@ that are a preferred form of the heading. sub preferred_authorities { my $self = shift; - my $query = "Match-heading-see-from,ext='$self->{'search_form'}'"; - $query .= $self->_query_limiters(); - my ($error, $results, $total_hits) = SimpleSearch( $query, undef, undef, [ "authorityserver" ] ); + my $skipmetadata = shift || undef; + my ( $results, $total ) = _search( 'see-from', $skipmetadata ); return $results; } -=head1 INTERNAL METHODS +=head2 valid_bib_heading_subfield -=head2 _query_limiters + if (C4::Heading::valid_bib_heading_subfield('100', 'e', '')) ... =cut -sub _query_limiters { - my $self = shift; +sub valid_bib_heading_subfield { + my $tag = shift; + my $subfield = shift; + my $marcflavour = @_ ? shift : C4::Context->preference('marcflavour'); - my $limiters = " AND at='$self->{'auth_type'}'"; - if ($self->{'subject_added_entry'}) { - $limiters .= " AND Heading-use-subject-added-entry=a"; # FIXME -- is this properly in C4::Heading::MARC21? - $limiters .= " AND Subject-heading-thesaurus=$self->{'thesaurus'}"; - } - if ($self->{'series_added_entry'}) { - $limiters .= " AND Heading-use-series-added-entry=a"; # FIXME -- is this properly in C4::Heading::MARC21? - } - if (not $self->{'subject_added_entry'} and not $self->{'series_added_entry'}) { - $limiters .= " AND Heading-use-main-or-added-entry=a" # FIXME -- is this properly in C4::Heading::MARC21? + my $marc_handler = _marc_format_handler($marcflavour); + + return $marc_handler->valid_bib_heading_subfield( $tag, $subfield ); +} + +=head1 INTERNAL METHODS + +=head2 _search + +=cut + +sub _search { + my $self = shift; + my $index = shift || undef; + my $skipmetadata = shift || undef; + my @marclist; + my @and_or; + my @excluding = []; + my @operator; + my @value; + + if ($index) { + push @marclist, $index; + push @and_or, 'and'; + push @operator, $self->{'match_type'}; + push @value, $self->{'search_form'}; } - return $limiters; + + # if ($self->{'thesaurus'}) { + # push @marclist, 'thesaurus'; + # push @and_or, 'and'; + # push @excluding, ''; + # push @operator, 'is'; + # push @value, $self->{'thesaurus'}; + # } + + require Koha::SearchEngine::QueryBuilder; + require Koha::SearchEngine::Search; + + # Use state variables to avoid recreating the objects every time. + # With Elasticsearch this also avoids creating a massive amount of + # ES connectors that would eventually run out of file descriptors. + state $builder = Koha::SearchEngine::QueryBuilder->new( + { index => $Koha::SearchEngine::AUTHORITIES_INDEX } ); + state $searcher = Koha::SearchEngine::Search->new( + {index => $Koha::SearchEngine::AUTHORITIES_INDEX} ); + + my $search_query = $builder->build_authorities_query_compat( + \@marclist, \@and_or, \@excluding, \@operator, + \@value, $self->{'auth_type'}, + 'AuthidAsc' + ); + return $searcher->search_auth_compat( $search_query, 0, 20, $skipmetadata ); } =head1 INTERNAL FUNCTIONS @@ -178,19 +246,16 @@ depending on the selected MARC flavour. =cut sub _marc_format_handler { - my $marcflavour = shift; - - if ($marcflavour eq 'UNIMARC') { - return C4::Heading::UNIMARC->new(); - } else { - return C4::Heading::MARC21->new(); - } - + my $marcflavour = uc shift; + $marcflavour = 'MARC21' if ( $marcflavour eq 'NORMARC' ); + my $pname = "C4::Heading::$marcflavour"; + load $pname; + return $pname->new(); } =head1 AUTHOR -Koha Developement team +Koha Development Team Galen Charlton