From f8df7b952d5f90171cc2c6e0d8ec108cd20fa36f Mon Sep 17 00:00:00 2001 From: Fridolyn SOMERS Date: Tue, 27 Nov 2012 17:12:48 +0100 Subject: [PATCH] Bug 7933: Fields in marc display not the same --- C4/Biblio.pm | 124 +++++++++++++++++++++++++++++++++++++------- C4/Record.pm | 56 ++++++++++++-------- C4/Search.pm | 1 + opac/opac-ISBDdetail.pl | 2 +- opac/opac-MARCdetail.pl | 8 +-- opac/opac-basket.pl | 2 +- opac/opac-detail.pl | 2 +- opac/opac-downloadcart.pl | 4 +- opac/opac-downloadshelf.pl | 4 +- opac/opac-export.pl | 4 +- opac/opac-reserve.pl | 8 +-- opac/opac-search.pl | 2 +- opac/opac-sendbasket.pl | 2 +- opac/opac-sendshelf.pl | 2 +- opac/opac-showmarc.pl | 5 +- opac/opac-showreviews.pl | 2 +- 16 files changed, 164 insertions(+), 64 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 16134d4..cbd9069 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -76,6 +76,7 @@ BEGIN { &GetMarcISSN &GetMarcSubjects &GetMarcBiblio + &GetMarcBiblioForOpac &GetMarcAuthors &GetMarcSeries &GetMarcHosts @@ -138,6 +139,7 @@ BEGIN { &TransformHtmlToXml &GetNoZebraIndexes prepare_host_field + &RemoveHiddenSubfields ); } @@ -908,16 +910,21 @@ sub GetBiblioFromItemNumber { =head2 GetISBDView - $isbd = &GetISBDView($biblionumber); + $isbd = &GetISBDView($biblionumber, [$template]); -Return the ISBD view which can be included in opac and intranet +Returns the ISBD view which can be included in opac and intranet. + +C<$template> - 'opac' or 'intranet', default 'intranet' =cut sub GetISBDView { - my ( $biblionumber, $template ) = @_; - my $record = GetMarcBiblio($biblionumber, 1); + my $biblionumber = shift; + my $template = shift || 'intranet'; + + my $record = ($template eq 'opac') ? GetMarcBiblioForOpac($biblionumber, 1) : GetMarcBiblio($biblionumber, 1); return unless defined $record; + my $itemtype = &GetFrameworkCode($biblionumber); my ( $holdingbrtagf, $holdingbrtagsubf ) = &GetMarcFromKohaField( "items.holdingbranch", $itemtype ); my $tagslib = &GetMarcStructure( 1, $itemtype ); @@ -1248,38 +1255,67 @@ sub GetMarcSubfieldStructureFromKohaField { =head2 GetMarcBiblio - my $record = GetMarcBiblio($biblionumber, [$embeditems]); + my $record = GetMarcBiblio($biblionumber, [$embeditems], [$template], [$withouthidden]); + +Returns MARC::Record representing bib. If no bib exists, returns undef. + +C<$biblionumber> - the biblionumber of the biblio -Returns MARC::Record representing bib identified by -C<$biblionumber>. If no bib exists, returns undef. -C<$embeditems>. If set to true, items data are included. -The MARC record contains biblio data, and items data if $embeditems is set to true. +C<$embeditems> - if set to true items data are included, default false + +C<$template> - 'opac' or 'intranet', default 'intranet' + +C<$withouthidden> - if set to true hidden subfields are not included, default false =cut sub GetMarcBiblio { my $biblionumber = shift; my $embeditems = shift || 0; + my $template = shift || 'intranet'; + my $withouthidden = shift || 0; + my $dbh = C4::Context->dbh; my $sth = $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? "); $sth->execute($biblionumber); my $row = $sth->fetchrow_hashref; my $marcxml = StripNonXmlChars( $row->{'marcxml'} ); + return unless $marcxml; + MARC::File::XML->default_record_format( C4::Context->preference('marcflavour') ); my $record = MARC::Record->new(); + $record = eval { MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour') ) }; + if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; } + return unless $record; - if ($marcxml) { - $record = eval { MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour') ) }; - if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; } - return unless $record; - - C4::Biblio::_koha_marc_update_bib_ids($record, '', $biblionumber, $biblionumber); - C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems); + C4::Biblio::_koha_marc_update_bib_ids($record, '', $biblionumber, $biblionumber); + C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems); - return $record; - } else { - return; + if ($withouthidden) { + my $frameworkcode = GetFrameworkCode( $biblionumber ); + RemoveHiddenSubfields($record, $frameworkcode, $template); } + + return $record; +} + +=head2 GetMarcBiblioForOpac + + my $record = GetMarcBiblioForOpac($biblionumber, [$embeditems]); + +Returns MARC::Record representing bib. If no bib exists, returns undef. +The record does not contain subfields hidden at OPAC. + +C<$biblionumber> - the biblionumber of the biblio + +C<$embeditems> - if set to true items data are included, default false + +=cut + +sub GetMarcBiblioForOpac { + my $biblionumber = shift; + my $embeditems = shift || 0; + return GetMarcBiblio($biblionumber, $embeditems, 'opac', 1); } =head2 GetXmlBiblio @@ -4002,6 +4038,56 @@ sub RemoveAllNsb { return $record; } +=head2 RemoveHiddenSubfields + + RemoveHiddenSubfields( $biblionumber, [$frameworkcode], [$template] ); + + Removes from record all subfields marked as hidden. + +=cut + +sub RemoveHiddenSubfields { + my $record = shift; + my $frameworkcode = shift || ''; + my $template = shift || 'intranet'; + + my $tagslib = GetMarcStructure( 0, $frameworkcode ); + + foreach my $tag ( keys %$tagslib ) { + my @fields = $record->field($tag); + next unless @fields; + + my @subfields_to_remove; + foreach my $subfield ( keys %{ $tagslib->{$tag} } ) { + # skip tag infos + next unless ( ref( $tagslib->{$tag}->{$subfield} ) eq "HASH" ); + if ( $template eq 'opac' ) { + push @subfields_to_remove, $subfield + if $tagslib->{$tag}->{$subfield}->{'hidden'} > 0; + } + else { + push @subfields_to_remove, $subfield + if $tagslib->{$tag}->{$subfield}->{'hidden'} =~ + /-7|-4|-3|-2|2|3|5|8/; + } + } + if ( @subfields_to_remove ) { + foreach my $field (@fields) { + if ( $tag < 10 ) { + # control field so delete entire field + $record->delete_field($field); + } + else { + $field->delete_subfield( code => \@subfields_to_remove ); + # delete field if no subfield anymore + $record->delete_field($field) + unless ( $field->subfields() ); + } + } + } + } +} + 1; diff --git a/C4/Record.pm b/C4/Record.pm index f75195f..a09e91f 100644 --- a/C4/Record.pm +++ b/C4/Record.pm @@ -358,7 +358,7 @@ sub marc2endnote { =head2 marc2csv - Convert several records from UNIMARC to CSV - my ($csv) = marc2csv($biblios, $csvprofileid, $itemnumbers); + my ($csv) = marc2csv($biblios, $csvprofileid, [$itemnumbers], [$template]); Pre and postprocessing can be done through a YAML file @@ -370,13 +370,20 @@ C<$csvprofileid> - the id of the CSV profile to use for the export (see export_f C<$itemnumbers> - a list of itemnumbers to export +C<$template> - 'opac' or 'intranet', default 'intranet' + =cut sub marc2csv { - my ($biblios, $id, $itemnumbers) = @_; + my ($biblios, $id, $itemnumbers, $template) = @_; + $template ||= 'intranet'; my $output; my $csv = Text::CSV::Encoded->new(); + # Getting information about the csv profile + my $profile = GetCsvProfile($id); + return unless $profile; + # Getting yaml file my $configfile = "../tools/csv-profiles/$id.yaml"; my ($preprocess, $postprocess, $fieldprocessing); @@ -390,13 +397,28 @@ sub marc2csv { my $firstpass = 1; if ( $itemnumbers ) { for my $itemnumber ( @$itemnumbers) { + my $biblionumber = GetBiblionumberFromItemnumber $itemnumber; - $output .= marcrecord2csv( $biblionumber, $id, $firstpass, $csv, $fieldprocessing, [$itemnumber] ); + next unless $biblionumber; + + my $record = ($template eq 'opac') ? GetMarcBiblioForOpac($biblionumber) : GetMarcBiblio($biblionumber); + next unless $record; + C4::Biblio::EmbedItemsInMarcBiblio( $record, $biblionumber, $itemnumbers ); + + my $frameworkcode = GetFrameworkCode($biblionumber); + + $output .= _marcrecord2csv( $record, $frameworkcode, $profile, $firstpass, $csv, $fieldprocessing, [$itemnumber] ); $firstpass = 0; } } else { foreach my $biblio (@$biblios) { - $output .= marcrecord2csv( $biblio, $id, $firstpass, $csv, $fieldprocessing ); + + my $record = ($template eq 'opac') ? GetMarcBiblioForOpac($biblio) : GetMarcBiblio($biblio); + next unless $record; + + my $frameworkcode = GetFrameworkCode($biblio); + + $output .= _marcrecord2csv( $record, $frameworkcode, $profile, $firstpass, $csv, $fieldprocessing ); $firstpass = 0; } } @@ -407,15 +429,17 @@ sub marc2csv { return $output; } -=head2 marcrecord2csv - Convert a single record from UNIMARC to CSV +=head2 _marcrecord2csv - Convert a single record from UNIMARC to CSV - my ($csv) = marcrecord2csv($biblio, $csvprofileid, $header); + my ($csv) = _marcrecord2csv($biblio, $csvprofileid, $header); Returns a CSV scalar -C<$biblio> - a biblionumber +C<$record> - a bib MARC::Record -C<$csvprofileid> - the id of the CSV profile to use for the export (see export_format.export_format_id and the GetCsvProfiles function in C4::Csv) +C<$frameworkcode> - framework code of record + +C<$csvprofile> - the CSV profile to use for the export C<$header> - true if the headers are to be printed (typically at first pass) @@ -423,25 +447,15 @@ C<$csv> - an already initialised Text::CSV object C<$fieldprocessing> -C<$itemnumbers> a list of itemnumbers to export +C<$itemnumbers> a list of item numbers to export =cut -sub marcrecord2csv { - my ($biblio, $id, $header, $csv, $fieldprocessing, $itemnumbers) = @_; +sub _marcrecord2csv { + my ($record, $frameworkcode, $profile, $header, $csv, $fieldprocessing, $itemnumbers) = @_; my $output; - # Getting the record - my $record = GetMarcBiblio($biblio); - next unless $record; - C4::Biblio::EmbedItemsInMarcBiblio( $record, $biblio, $itemnumbers ); - # Getting the framework - my $frameworkcode = GetFrameworkCode($biblio); - - # Getting information about the csv profile - my $profile = GetCsvProfile($id); - # Getting output encoding my $encoding = $profile->{encoding} || 'utf8'; # Getting separators diff --git a/C4/Search.pm b/C4/Search.pm index 65ad919..0095e9f 100644 --- a/C4/Search.pm +++ b/C4/Search.pm @@ -1714,6 +1714,7 @@ sub searchResults { : $bibliotag < 10 ? GetFrameworkCode($marcrecord->field($bibliotag)->data) : GetFrameworkCode($marcrecord->subfield($bibliotag,$bibliosubf)); + RemoveHiddenSubfields($marcrecord, $fw, $search_context) if ($search_context eq 'opac'); my $oldbiblio = TransformMarcToKoha( $dbh, $marcrecord, $fw ); $oldbiblio->{subtitle} = GetRecordValue('subtitle', $marcrecord, $fw); $oldbiblio->{result_number} = $i + 1; diff --git a/opac/opac-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index be62879..78eb08b 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -84,7 +84,7 @@ $template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHo $template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) ); my $marcflavour = C4::Context->preference("marcflavour"); -my $record = GetMarcBiblio($biblionumber); +my $record = GetMarcBiblioForOpac($biblionumber); if ( ! $record ) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); exit; diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index ac13a9d..7b751f6 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -62,7 +62,7 @@ my $itemtype = &GetFrameworkCode($biblionumber); my $tagslib = &GetMarcStructure( 0, $itemtype ); my $biblio = GetBiblioData($biblionumber); $biblionumber = $biblio->{biblionumber}; -my $record = GetMarcBiblio($biblionumber, 1); +my $record = GetMarcBiblioForOpac($biblionumber, 1); if ( ! $record ) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); exit; @@ -114,8 +114,7 @@ for ( my $tabloop = 0 ; $tabloop <= 9 ; $tabloop++ ) { my @subfields_data; # deal with leader - unless ( $tagslib->{'000'}->{'@'}->{tab} ne $tabloop - or $tagslib->{'000'}->{'@'}->{hidden} > 0 ) + unless ( $tagslib->{'000'}->{'@'}->{tab} ne $tabloop ) { my %subfield_data; $subfield_data{marc_lib} = $tagslib->{'000'}->{'@'}->{lib}; @@ -138,7 +137,6 @@ for ( my $tabloop = 0 ; $tabloop <= 9 ; $tabloop++ ) { next if ( $tagslib->{ $fields[$x_i]->tag() }->{'@'}->{tab} ne $tabloop ); - next if ( $tagslib->{ $fields[$x_i]->tag() }->{'@'}->{hidden} > 0 ); my %subfield_data; $subfield_data{marc_lib} = $tagslib->{ $fields[$x_i]->tag() }->{'@'}->{lib}; @@ -155,7 +153,6 @@ for ( my $tabloop = 0 ; $tabloop <= 9 ; $tabloop++ ) { $subf[$i][0] = "@" unless defined($subf[$i][0]); my $sf_def = $tagslib->{ $fields[$x_i]->tag() }->{ $subf[$i][0] }; next if ( ($sf_def->{tab}||0) != $tabloop ); - next if ( ($sf_def->{hidden}||0) > 0 ); my %subfield_data; $subfield_data{marc_lib} = ($sf_def->{lib} eq $previous) ? '--' : $sf_def->{lib}; $previous = $sf_def->{lib}; @@ -228,7 +225,6 @@ foreach my $field (@fields) { for my $i ( 0 .. $#subf ) { my $sf_def = $tagslib->{ $field->tag() }->{ $subf[$i][0] }; next if ( ($sf_def->{tab}||0) != 10 ); - next if ( ($sf_def->{hidden}||0) > 0 ); $witness{ $subf[$i][0] } = $sf_def->{lib}; if ( $sf_def->{isurl} ) { diff --git a/opac/opac-basket.pl b/opac/opac-basket.pl index cf75eb7..110a6d4 100755 --- a/opac/opac-basket.pl +++ b/opac/opac-basket.pl @@ -63,7 +63,7 @@ foreach my $biblionumber ( @bibs ) { $template->param( biblionumber => $biblionumber ); my $dat = &GetBiblioData($biblionumber); - my $record = &GetMarcBiblio($biblionumber); + my $record = &GetMarcBiblioForOpac($biblionumber); next unless $record; my $marcnotesarray = GetMarcNotes( $record, $marcflavour ); my $marcauthorsarray = GetMarcAuthors( $record, $marcflavour ); diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 068122e..011e75e 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -72,7 +72,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( my $biblionumber = $query->param('biblionumber') || $query->param('bib'); $biblionumber = int($biblionumber); -my $record = GetMarcBiblio($biblionumber); +my $record = GetMarcBiblioForOpac($biblionumber); if ( ! $record ) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); # escape early exit; diff --git a/opac/opac-downloadcart.pl b/opac/opac-downloadcart.pl index 3a4cdc1..00b6360 100755 --- a/opac/opac-downloadcart.pl +++ b/opac/opac-downloadcart.pl @@ -58,13 +58,13 @@ if ($bib_list && $format) { # CSV if ($format =~ /^\d+$/) { - $output = marc2csv(\@bibs, $format); + $output = marc2csv(\@bibs, $format, undef, 'opac'); # Other formats } else { foreach my $biblio (@bibs) { - my $record = GetMarcBiblio($biblio, 1); + my $record = GetMarcBiblioForOpac($biblio, 1); next unless $record; if ($format eq 'iso2709') { diff --git a/opac/opac-downloadshelf.pl b/opac/opac-downloadshelf.pl index 662eb25..a769e54 100755 --- a/opac/opac-downloadshelf.pl +++ b/opac/opac-downloadshelf.pl @@ -62,14 +62,14 @@ if ( ShelfPossibleAction( (defined($borrowernumber) ? $borrowernumber : -1), $sh foreach (@$items) { push @biblios, $_->{biblionumber}; } - $output = marc2csv(\@biblios, $format); + $output = marc2csv(\@biblios, $format, undef, 'opac'); # Other formats } else { foreach my $biblio (@$items) { my $biblionumber = $biblio->{biblionumber}; - my $record = GetMarcBiblio($biblionumber, 1); + my $record = GetMarcBiblioForOpac($biblionumber, 1); next unless $record; if ($format eq 'iso2709') { diff --git a/opac/opac-export.pl b/opac/opac-export.pl index 002c88e..9853cdf 100755 --- a/opac/opac-export.pl +++ b/opac/opac-export.pl @@ -35,7 +35,7 @@ my $biblionumber = $query->param("bib")||0; $biblionumber = int($biblionumber); my ($marc, $error)= ('',''); -$marc = GetMarcBiblio($biblionumber, 1) if $biblionumber; +$marc = GetMarcBiblioForOpac($biblionumber, 1) if $biblionumber; if(!$marc) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); exit; @@ -57,7 +57,7 @@ elsif ($format =~ /ris/) { $format = 'ris'; } elsif ($format =~ /bibtex/) { - $marc = marc2bibtex(C4::Biblio::GetMarcBiblio($biblionumber),$biblionumber); + $marc = marc2bibtex(C4::Biblio::GetMarcBiblioForOpac($biblionumber),$biblionumber); $format = 'bibtex'; } elsif ($format =~ /dc/) { diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 07b4f76..4470b80 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -131,7 +131,10 @@ foreach my $biblioNumber (@biblionumbers) { my @itemInfos = GetItemsInfo($biblioNumber); - my $marcrecord= GetMarcBiblio($biblioNumber); + my $marcrecord= GetMarcBiblioForOpac($biblioNumber); + + # subtitle + $biblioData->{subtitle} = GetRecordValue('subtitle', $marcrecord, GetFrameworkCode($biblioNumber)); # flag indicating existence of at least one item linked via a host record my $hostitemsflag; @@ -356,7 +359,6 @@ $template->param('item_level_itypes' => $itemLevelTypes); foreach my $biblioNum (@biblionumbers) { - my $record = GetMarcBiblio($biblioNum); # Init the bib item with the choices for branch pickup my %biblioLoopIter = ( branchChoicesLoop => $CGIbranchloop ); @@ -369,7 +371,7 @@ foreach my $biblioNum (@biblionumbers) { $biblioLoopIter{biblionumber} = $biblioData->{biblionumber}; $biblioLoopIter{title} = $biblioData->{title}; - $biblioLoopIter{subtitle} = GetRecordValue('subtitle', $record, GetFrameworkCode($biblioData->{biblionumber})); + $biblioLoopIter{subtitle} = $biblioData->{subtitle}; $biblioLoopIter{author} = $biblioData->{author}; $biblioLoopIter{rank} = $biblioData->{rank}; $biblioLoopIter{reservecount} = $biblioData->{reservecount}; diff --git a/opac/opac-search.pl b/opac/opac-search.pl index d2ba9fc..57b50d4 100755 --- a/opac/opac-search.pl +++ b/opac/opac-search.pl @@ -569,7 +569,7 @@ for (my $i=0;$i<@servers;$i++) { if (C4::Context->preference('COinSinOPACResults')) { foreach (@newresults) { - my $record = GetMarcBiblio($_->{'biblionumber'}); + my $record = GetMarcBiblioForOpac($_->{'biblionumber'}); $_->{coins} = GetCOinSBiblio($record); if ( C4::Context->preference( "Babeltheque" ) and $_->{normalized_isbn} ) { my $isbn = Business::ISBN->new( $_->{normalized_isbn} ); diff --git a/opac/opac-sendbasket.pl b/opac/opac-sendbasket.pl index da74745..d584b18 100755 --- a/opac/opac-sendbasket.pl +++ b/opac/opac-sendbasket.pl @@ -87,7 +87,7 @@ if ( $email_add ) { $template2->param( biblionumber => $biblionumber ); my $dat = GetBiblioData($biblionumber); - my $record = GetMarcBiblio($biblionumber); + my $record = GetMarcBiblioForOpac($biblionumber); my $marcnotesarray = GetMarcNotes( $record, $marcflavour ); my $marcauthorsarray = GetMarcAuthors( $record, $marcflavour ); my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour ); diff --git a/opac/opac-sendshelf.pl b/opac/opac-sendshelf.pl index 6e60bc9..854d2ac 100755 --- a/opac/opac-sendshelf.pl +++ b/opac/opac-sendshelf.pl @@ -83,7 +83,7 @@ if ( $email ) { my $biblionumber = $biblio->{biblionumber}; my $fw = GetFrameworkCode($biblionumber); my $dat = GetBiblioData($biblionumber); - my $record = GetMarcBiblio($biblionumber); + my $record = GetMarcBiblioForOpac($biblionumber); my $marcnotesarray = GetMarcNotes( $record, $marcflavour ); my $marcauthorsarray = GetMarcAuthors( $record, $marcflavour ); my $marcsubjctsarray = GetMarcSubjects( $record, $marcflavour ); diff --git a/opac/opac-showmarc.pl b/opac/opac-showmarc.pl index 71fb804..c76d3fc 100755 --- a/opac/opac-showmarc.pl +++ b/opac/opac-showmarc.pl @@ -52,11 +52,12 @@ if ($importid) { $record = MARC::Record->new_from_usmarc($marc); } else { - $record =GetMarcBiblio($biblionumber); + $record = GetMarcBiblioForOpac($biblionumber); } if ($view eq 'card' || $view eq 'html') { - my $xmlrecord= $importid? $record->as_xml(): GetXmlBiblio($biblionumber); + my $xmlrecord= $record->as_xml(); + my $xslfile; my $xslfilename; my $htdocs = C4::Context->config('opachtdocs'); diff --git a/opac/opac-showreviews.pl b/opac/opac-showreviews.pl index 151c101..8122283 100755 --- a/opac/opac-showreviews.pl +++ b/opac/opac-showreviews.pl @@ -84,7 +84,7 @@ my $latest_comment_date; for my $result (@$reviews){ my $biblionumber = $result->{biblionumber}; my $bib = &GetBiblioData($biblionumber); - my $record = GetMarcBiblio($biblionumber); + my $record = GetMarcBiblioForOpac($biblionumber); my $frameworkcode = GetFrameworkCode($biblionumber); my ( $borr ) = GetMemberDetails( $result->{borrowernumber} ); $result->{normalized_upc} = GetNormalizedUPC($record,$marcflavour); -- 1.7.10.4