From 7bd1ed4add97cb02b49e98abcb85197616fb4ac0 Mon Sep 17 00:00:00 2001 From: Mark Tompsett Date: Tue, 14 Jan 2014 11:31:36 -0500 Subject: [PATCH] Bug 11592 - opac scripts do not respect marc tag visibility Added two functions to C4/Biblio: GetFilteredOpacBiblio and GetOpacHideMARC. GetFilteredOpacBiblio returns a MARC::Record stripped of all the fields and subfields which are supposed to be hidden in OPAC. GetOpacHideMARC returns a hash of whether a particular key (eg. title, subtitle, etc.) is hidden. A value of 0 means no, a value of 1 means hidden. Made GetCOinSBiblio function handle hiding of 245$a more gracefully. Also, modified GetMarcSubjects to not generate an array entry of empty values. Tweaked C4/XSLT.pm to delete a field, if there weren't any subfields to actually update with. Properly hid 245$a, in the case that there is no visibility for OPAC, for opac-MARCdetail. opac-detail now filters the MARC::Record according to the hidden value in marc_subfield_structure properly. It also corrects a couple minor issues with a parameter not passed being used in a concatenation. How the subtitle values calculation works changed. It is now based on marc_subfield_structure and not fieldmapping. And, the GetBiblioData hash that generates template variables is now filtered by the results of a GetOpacHideMARC call. Lastly, opac-showmarc now converts the MARCXML record to a MARC::Record to easily filter using GetFilteredOpacBiblio, which is then turned back into MARCXML for processing. --- C4/Biblio.pm | 106 ++++++++++++++++++++++++++++++++++++++++++++++- C4/XSLT.pm | 17 +++++--- opac/opac-MARCdetail.pl | 3 +- opac/opac-detail.pl | 21 ++++++++-- opac/opac-showmarc.pl | 6 +++ 5 files changed, 141 insertions(+), 12 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index dc40d68..157f26a 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -79,6 +79,8 @@ BEGIN { &GetMarcSeries &GetMarcHosts GetMarcUrls + &GetOpacHideMARC + &GetFilteredOpacBiblio &GetUsedMarcStructure &GetXmlBiblio &GetCOinSBiblio @@ -1207,6 +1209,105 @@ sub GetUsedMarcStructure { return $sth->fetchall_arrayref( {} ); } +=head2 GetOpacHideMARC + +Return a hash reference of whether a field, built from +kohafield and tag, is hidden in OPAC (1) or not (0). + + my $OpacHideMARC = GetOpacHideMARC($frameworkcode); + + if ($OpacHideMARC->{'stocknumber'}==1) { + print "Hidden!\n"; + } + +C<$OpacHideMARC> is a ref to a hash which contains a series +of key value pairs indicating if that field (key) is +hidden (value == 1) or not (value == 0). + +C<$frameworkcode> is the framework code. + +=cut + +sub GetOpacHideMARC { + my ( $frameworkcode ) = shift || ''; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT SUBSTRING(kohafield,LOCATE('.',kohafield)+1,40) AS field,tagfield AS tag,hidden FROM marc_subfield_structure WHERE LENGTH(TRIM(kohafield))>0 AND frameworkcode=? ORDER BY field,tagfield;"); + my $rv = $sth->execute($frameworkcode); + my %opachidemarc; + my $data = $sth->fetchall_hashref( [ qw(field tag) ] ); + foreach my $field (keys %{$data}) { + foreach my $tag (keys %{$data->{$field}}) { + if ($data->{$field}->{$tag}->{'hidden'}>0) { + $opachidemarc{ $field } = 1; + } + elsif ( !exists($opachidemarc{ $field }) ) { + $opachidemarc{ $field } = 0; + } + } + } + return \%opachidemarc; +} + +=head2 GetFilteredOpacBiblio + +Return a MARC::Record which has been filtered based +on the corresponding marc_subfield_structure records +for the given framework by excluding hidden>0. + + my $filtered_record = GetFilteredOpacBiblio($record,$frameworkcode); + +C<$record> is a MARC::Record. + +C<$frameworkcode> is the framework code. + +=cut + +sub GetFilteredOpacBiblio { + my ( $record ) = shift; + if (!$record) { return $record; } + + my ( $frameworkcode ) = shift || ''; + + my $marcsubfieldstructure = GetMarcStructure(0,$frameworkcode); + if ($marcsubfieldstructure->{'000'}->{'@'}->{hidden}>0) { + # LDR field is excluded from $record->fields(). + # if we hide it here, the MARCXML->MARC::Record->MARCXML transformation blows up. + print STDERR "Supposed to hide LEADER\n"; + } + foreach my $fields ($record->fields()) { + my $tag = $fields->tag(); + if ($tag>=10) { + foreach my $subpairs ($fields->subfields()) { + my ($subtag,$value) = @$subpairs; + my $hidden = $marcsubfieldstructure->{$tag}->{$subtag}->{hidden}; + $hidden //= 0; + $hidden = ($hidden<=0) ? 0 : 1; + if ($hidden) { + # deleting last subfield doesn't delete field, so + # this detects that case to delete the field. + if (scalar $fields->subfields() <= 1) { + $record->delete_fields($fields); + } + else { + $fields->delete_subfield( code => $subtag ); + } + } + } + } + # tags less than 10 don't have subfields, use @ trick. + else { + my $hidden = $marcsubfieldstructure->{$tag}->{'@'}->{hidden}; + $hidden //= 0; + $hidden = ($hidden<=0) ? 0 : 1; + if ($hidden) { + $record->delete_fields($fields); + } + } + } + + return $record; +} + =head2 GetMarcFromKohaField ($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode); @@ -1427,7 +1528,8 @@ sub GetCOinSBiblio { $oauthors .= "&rft.au=$au"; } } - $title = "&rft." . $titletype . "title=" . $record->subfield( '245', 'a' ); + $title = $record->subfield( '245', 'a' ) || ''; + $title = "&rft." . $titletype . "title=" . $title; $subtitle = $record->subfield( '245', 'b' ) || ''; $title .= $subtitle; if ($titletype eq 'a') { @@ -1873,7 +1975,7 @@ sub GetMarcSubjects { push @marcsubjects, { MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop, authoritylink => $authoritylink, - }; + } if $authoritylink || $#subfields_loop>=0; } return \@marcsubjects; diff --git a/C4/XSLT.pm b/C4/XSLT.pm index d85b048..2a43a41 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -93,12 +93,17 @@ sub transformMARCXML4XSLT { if $av->{ $tag }->{ $letter }; push( @new_subfields, $letter, $value ); } - $field ->replace_with( MARC::Field->new( - $tag, - $field->indicator(1), - $field->indicator(2), - @new_subfields - ) ); + if (@new_subfields) { + $field ->replace_with( MARC::Field->new( + $tag, + $field->indicator(1), + $field->indicator(2), + @new_subfields + ) ); + } + else { + $record->delete_fields($field); + } } } } diff --git a/opac/opac-MARCdetail.pl b/opac/opac-MARCdetail.pl index aaa565d..8a999dd 100755 --- a/opac/opac-MARCdetail.pl +++ b/opac/opac-MARCdetail.pl @@ -98,9 +98,10 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( } ); +my ($bt_tag,$bt_subtag) = GetMarcFromKohaField('biblio.title',$itemtype); $template->param( bibliotitle => $biblio->{title}, -); +) if $tagslib->{$bt_tag}->{$bt_subtag}->{hidden} <= 0; # get biblionumbers stored in the cart my @cart_list; diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 77de12f..6154646 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -91,6 +91,10 @@ if ( ! $record ) { } $template->param( biblionumber => $biblionumber ); +# Filter out the things to hide in OPAC. +my $frameworkcode = GetFrameworkCode($biblionumber); +#$record = GetFilteredOpacBiblio($record,$frameworkcode); + # get biblionumbers stored in the cart my @cart_list; @@ -377,13 +381,13 @@ if ($session->param('busc')) { my ($previous, $next, $dataBiblioPaging); # Previous biblio if ($paging{'previous'}->{biblionumber}) { - $previous = 'opac-detail.pl?biblionumber=' . $paging{'previous'}->{biblionumber} . '&query_desc=' . $query->param('query_desc'); + $previous = 'opac-detail.pl?biblionumber=' . $paging{'previous'}->{biblionumber} . '&query_desc=' . ($query->param('query_desc') // ''); $dataBiblioPaging = GetBiblioData($paging{'previous'}->{biblionumber}); $template->param('previousTitle' => $dataBiblioPaging->{'title'}) if ($dataBiblioPaging); } # Next biblio if ($paging{'next'}->{biblionumber}) { - $next = 'opac-detail.pl?biblionumber=' . $paging{'next'}->{biblionumber} . '&query_desc=' . $query->param('query_desc'); + $next = 'opac-detail.pl?biblionumber=' . $paging{'next'}->{biblionumber} . '&query_desc=' . ($query->param('query_desc') // ''); $dataBiblioPaging = GetBiblioData($paging{'next'}->{biblionumber}); $template->param('nextTitle' => $dataBiblioPaging->{'title'}) if ($dataBiblioPaging); } @@ -485,6 +489,7 @@ if ( C4::Context->preference('HighlightOwnItemsOnOPAC') ) { } my $dat = &GetBiblioData($biblionumber); +my $OpacHideMARC = &GetOpacHideMARC($dat->{'frameworkcode'}); my $itemtypes = GetItemTypes(); # imageurl: @@ -646,7 +651,16 @@ my $marcsubjctsarray = GetMarcSubjects($record,$marcflavour); my $marcseriesarray = GetMarcSeries ($record,$marcflavour); my $marcurlsarray = GetMarcUrls ($record,$marcflavour); my $marchostsarray = GetMarcHosts($record,$marcflavour); -my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($biblionumber)); +my ($st_tag,$st_subtag) = GetMarcFromKohaField('bibliosubtitle.subtitle',$dat->{'frameworkcode'}); +my $subtitle; +if ($st_tag && $st_subtag) { + my @subtitles = $record->subfield($st_tag,$st_subtag); + $subtitle = \@subtitles if scalar @subtitles; +} +if (scalar @$subtitle) { + my @subtitles = map { { subfield => $_ } } @$subtitle; + $subtitle = \@subtitles; +} $template->param( MARCNOTES => $marcnotesarray, @@ -696,6 +710,7 @@ if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { } foreach ( keys %{$dat} ) { + next if ( $OpacHideMARC->{$_} ); $template->param( "$_" => defined $dat->{$_} ? $dat->{$_} : '' ); } diff --git a/opac/opac-showmarc.pl b/opac/opac-showmarc.pl index 71fb804..380038b 100755 --- a/opac/opac-showmarc.pl +++ b/opac/opac-showmarc.pl @@ -57,6 +57,12 @@ else { if ($view eq 'card' || $view eq 'html') { my $xmlrecord= $importid? $record->as_xml(): GetXmlBiblio($biblionumber); + if (!$importid && $view eq 'html') { + my $filtered_record = MARC::Record->new_from_xml($xmlrecord); + my $frameworkcode = GetFrameworkCode($biblionumber); + $filtered_record = GetFilteredOpacBiblio($filtered_record,$frameworkcode); + $xmlrecord = $filtered_record->as_xml(); + } my $xslfile; my $xslfilename; my $htdocs = C4::Context->config('opachtdocs'); -- 1.7.9.5