X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=Koha%2FBiblio.pm;h=5bf369cd6a149f163570db9d3118ad4707d3dc2a;hb=2d25c2860c4b06a63048834fb99b2968f1fd57b1;hp=ea0c9d9f84abd16235101751b82644259d16e6c9;hpb=8757023b2167bfec92a494873232f1aaa76ab6be;p=koha-ffzg.git diff --git a/Koha/Biblio.pm b/Koha/Biblio.pm index ea0c9d9f84..5bf369cd6a 100644 --- a/Koha/Biblio.pm +++ b/Koha/Biblio.pm @@ -24,7 +24,6 @@ use URI; use URI::Escape qw( uri_escape_utf8 ); use C4::Koha qw( GetNormalizedISBN ); -use C4::XSLT qw( transformMARCXML4XSLT ); use Koha::Database; use Koha::DateUtils qw( dt_from_string ); @@ -34,6 +33,7 @@ use base qw(Koha::Object); use Koha::Acquisition::Orders; use Koha::ArticleRequests; use Koha::Biblio::Metadatas; +use Koha::Biblio::ItemGroups; use Koha::Biblioitems; use Koha::Checkouts; use Koha::CirculationRules; @@ -42,6 +42,7 @@ use Koha::Items; use Koha::Libraries; use Koha::Old::Checkouts; use Koha::Recalls; +use Koha::RecordProcessor; use Koha::Suggestions; use Koha::Subscriptions; use Koha::SearchEngine; @@ -118,6 +119,21 @@ sub active_orders { return $self->orders->search({ datecancellationprinted => undef }); } +=head3 item_groups + +my $item_groups = $biblio->item_groups(); + +Returns a Koha::Biblio::ItemGroups object + +=cut + +sub item_groups { + my ( $self ) = @_; + + my $item_groups = $self->_result->item_groups; + return Koha::Biblio::ItemGroups->_new_from_dbic($item_groups); +} + =head3 can_article_request my $bool = $biblio->can_article_request( $borrower ); @@ -579,12 +595,12 @@ sub get_components_query { if ( !defined($pf003) ) { # search for 773$w='Host001' - $searchstr .= "rcn:" . $pf001->data(); + $searchstr .= "rcn:\"" . $pf001->data()."\""; } else { $searchstr .= "("; # search for (773$w='Host001' and 003='Host003') or 773$w='(Host003)Host001' - $searchstr .= "(rcn:" . $pf001->data() . " AND cni:" . $pf003->data() . ")"; + $searchstr .= "(rcn:\"" . $pf001->data() . "\" AND cni:\"" . $pf003->data() . "\")"; $searchstr .= " OR rcn:\"" . $pf003->data() . " " . $pf001->data() . "\""; $searchstr .= ")"; } @@ -598,15 +614,15 @@ sub get_components_query { my $cleaned_title = $marc->subfield('245', "a"); $cleaned_title =~ tr|/||; $cleaned_title = $builder->clean_search_term($cleaned_title); - $searchstr = "Host-item:($cleaned_title)"; + $searchstr = qq#Host-item:("$cleaned_title")#; } - my ($error, $query_str) = $builder->build_query_compat( undef, [$searchstr], undef, undef, [$sort], 0 ); + my ($error, $query ,$query_str) = $builder->build_query_compat( undef, [$searchstr], undef, undef, [$sort], 0 ); if( $error ){ warn $error; return; } - return ($query_str, $sort); + return ($query, $query_str, $sort); } =head3 subscriptions @@ -933,11 +949,22 @@ sub get_marc_notes { my ( $self, $params ) = @_; my $marcflavour = C4::Context->preference('marcflavour'); - my $opac = $params->{opac}; + my $opac = $params->{opac} // '0'; + my $interface = $params->{opac} ? 'opac' : 'intranet'; - my $scope = $marcflavour eq "UNIMARC"? '3..': '5..'; - my @marcnotes; + my $record = $params->{record} // $self->metadata->record; + my $record_processor = Koha::RecordProcessor->new( + { + filters => [ 'ViewPolicy', 'ExpandCodedFields' ], + options => { + interface => $interface, + frameworkcode => $self->frameworkcode + } + } + ); + $record_processor->process($record); + my $scope = $marcflavour eq "UNIMARC"? '3..': '5..'; #MARC21 specs indicate some notes should be private if first indicator 0 my %maybe_private = ( 541 => 1, @@ -949,9 +976,8 @@ sub get_marc_notes { my %hiddenlist = map { $_ => 1 } split( /,/, C4::Context->preference('NotesToHide')); - my $record = $self->metadata->record; - $record = transformMARCXML4XSLT( $self->biblionumber, $record, $opac ); + my @marcnotes; foreach my $field ( $record->field($scope) ) { my $tag = $field->tag(); next if $hiddenlist{ $tag }; @@ -975,39 +1001,35 @@ sub get_marc_notes { return \@marcnotes; } -=head3 get_marc_authors - - my $authors = $biblio->get_marc_authors; +=head3 _get_marc_authors -Get all authors from the MARC record and returns them in an array. -The authors are stored in different fields depending on MARC flavour +Private method to return the list of authors contained in the MARC record. +See get get_marc_contributors and get_marc_authors for the public methods. =cut -sub get_marc_authors { +sub _get_marc_authors { my ( $self, $params ) = @_; - my ( $mintag, $maxtag, $fields_filter ); - my $marcflavour = C4::Context->preference('marcflavour'); + my $fields_filter = $params->{fields_filter}; + my $mintag = $params->{mintag}; + my $maxtag = $params->{maxtag}; + + my $AuthoritySeparator = C4::Context->preference('AuthoritySeparator'); + my $marcflavour = C4::Context->preference('marcflavour'); # tagslib useful only for UNIMARC author responsibilities - my $tagslib; - if ( $marcflavour eq "UNIMARC" ) { - $tagslib = C4::Biblio::GetMarcStructure( 1, $self->frameworkcode, { unsafe => 1 }); - $mintag = "700"; - $maxtag = "712"; - $fields_filter = '7..'; - } else { # marc21/normarc - $mintag = "700"; - $maxtag = "720"; - $fields_filter = '7..'; - } + my $tagslib = $marcflavour eq "UNIMARC" + ? C4::Biblio::GetMarcStructure( 1, $self->frameworkcode, { unsafe => 1 } ) + : undef; my @marcauthors; - my $AuthoritySeparator = C4::Context->preference('AuthoritySeparator'); - foreach my $field ( $self->metadata->record->field($fields_filter) ) { - next unless $field->tag() >= $mintag && $field->tag() <= $maxtag; + + next + if $mintag && $field->tag() < $mintag + || $maxtag && $field->tag() > $maxtag; + my @subfields_loop; my @link_loop; my @subfields = $field->subfields(); @@ -1071,6 +1093,76 @@ sub get_marc_authors { return \@marcauthors; } +=head3 get_marc_contributors + + my $contributors = $biblio->get_marc_contributors; + +Get all contributors (but first author) from the MARC record and returns them in an array. +They are stored in different fields depending on MARC flavour (700..720 for MARC21) + +=cut + +sub get_marc_contributors { + my ( $self, $params ) = @_; + + my ( $mintag, $maxtag, $fields_filter ); + my $marcflavour = C4::Context->preference('marcflavour'); + + if ( $marcflavour eq "UNIMARC" ) { + $mintag = "700"; + $maxtag = "712"; + $fields_filter = '7..'; + } else { # marc21/normarc + $mintag = "700"; + $maxtag = "720"; + $fields_filter = '7..'; + } + + return $self->_get_marc_authors( + { + fields_filter => $fields_filter, + mintag => $mintag, + maxtag => $maxtag + } + ); +} + +=head3 get_marc_authors + + my $authors = $biblio->get_marc_authors; + +Get all authors from the MARC record and returns them in an array. +They are stored in different fields depending on MARC flavour +(main author from 100 then secondary authors from 700..720). + +=cut + +sub get_marc_authors { + my ( $self, $params ) = @_; + + my ( $mintag, $maxtag, $fields_filter ); + my $marcflavour = C4::Context->preference('marcflavour'); + + if ( $marcflavour eq "UNIMARC" ) { + $fields_filter = '200'; + } else { # marc21/normarc + $fields_filter = '100'; + } + + my @first_authors = @{$self->_get_marc_authors( + { + fields_filter => $fields_filter, + mintag => $mintag, + maxtag => $maxtag + } + )}; + + my @other_authors = @{$self->get_marc_contributors}; + + return [@first_authors, @other_authors]; +} + + =head3 to_api my $json = $biblio->to_api; @@ -1104,7 +1196,8 @@ sub to_api_mapping { unititle => 'uniform_title', seriestitle => 'series_title', copyrightdate => 'copyright_date', - datecreated => 'creation_date' + datecreated => 'creation_date', + deleted_on => undef, }; } @@ -1112,7 +1205,7 @@ sub to_api_mapping { $host = $biblio->get_marc_host; # OR: - ( $host, $relatedparts ) = $biblio->get_marc_host; + ( $host, $relatedparts, $hostinfo ) = $biblio->get_marc_host; Returns host biblio record from MARC21 773 (undef if no 773 present). It looks at the first 773 field with MARCorgCode or only a control @@ -1121,6 +1214,12 @@ sub to_api_mapping { If there are, the sub returns undef. Called in list context, it also returns 773$g (related parts). + If there is no $w, we use $0 (host biblionumber) or $9 (host itemnumber) + to search for the host record. If there is also no $0 and no $9, we search + using author and title. Failing all of that, we return an undef host and + form a concatenation of strings with 773$agt for host information, + returned when called in list context. + =cut sub get_marc_host { @@ -1144,12 +1243,35 @@ sub get_marc_host { last; } } + + my $engine = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); + my $bibno; + if ( !$hostfld and $record->subfield('773','t') ) { + # not linked using $w + my $unlinkedf = $record->field('773'); + my $host; + if ( C4::Context->preference("EasyAnalyticalRecords") ) { + if ( $unlinkedf->subfield('0') ) { + # use 773$0 host biblionumber + $bibno = $unlinkedf->subfield('0'); + } elsif ( $unlinkedf->subfield('9') ) { + # use 773$9 host itemnumber + my $linkeditemnumber = $unlinkedf->subfield('9'); + $bibno = Koha::Items->find( $linkeditemnumber )->biblionumber; + } + } + if ( $bibno ) { + my $host = Koha::Biblios->find($bibno) or return; + return wantarray ? ( $host, $unlinkedf->subfield('g') ) : $host; + } + # just return plaintext and no host record + my $hostinfo = join( ", ", $unlinkedf->subfield('a'), $unlinkedf->subfield('t'), $unlinkedf->subfield('g') ); + return wantarray ? ( undef, $unlinkedf->subfield('g'), $hostinfo ) : undef; + } return if !$hostfld; my $rcn = $hostfld->subfield('w'); # Look for control number with/without orgcode - my $engine = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX }); - my $bibno; for my $try (1..2) { my ( $error, $results, $total_hits ) = $engine->simple_search_compat( 'Control-number='.$rcn, 0,1 ); if( !$error and $total_hits == 1 ) {