From 79b8de782c2fe84baf97ce237e3df1f2ee0a4dee Mon Sep 17 00:00:00 2001 From: Mark Tompsett Date: Wed, 14 May 2014 22:49:41 -0400 Subject: [PATCH] Bug 11592 - MARC Visibility settings not respected The advanced constraints section while editing subfield structure for a particular MARC bibliographic framework allow the user to set visibility settings for OPAC and Intranet. These settings are not fully respected. This was first discovered while comparing the information displayed on the opac-MARCdetail and opac-detail pages. To this end, this patch will provide the ability to correct this problem across the board as desired, but will focus primarily on the OPAC interface. This was accomplished by adding 3 functions to C4/Biblio.pm: - ShouldDisplayOnInterface - ShouldHideMARC - GetFilteredBiblio And also by modifying GetMarcBiblio to filter or not based on parameter style and parameter values passed. ShouldDisplayOnInterface is a wrapper routine which just returns a hash of hashes which let us know if something is visible (1) or not (0 or undef) for a given interface (opac or intranet). This allows us to add/remove to the advance constraints section and then not have to update multiple routines to keep the filtering working properly, though if it is a drastic refactoring that would be necessary. ShouldHideMARC takes a field from marc_subfield_structure, and determines if it should be hidden. It does this for all the fields for a given framework code on a particular interface. If no framework code is given, the framework code used is the default one. If not interface is specified, OPAC is assumed. This routine returns a hash reference to the corresponding hash that was built. GetFilteredBiblio takes a MARC::Record, clones it, and then strips all the fields that should not be visible for a given framework code and interface. If no framework code is specied, it assumes the default one. If no interface is given, OPAC is assumed. The routine then returns the filtered record. GetMarcBiblio was modified to accept a hash style parameter. This allowed for filtering if the new convention was used, and no apparent change if the old convention is used. These functions allowed for filtering, but frequently there were problems with titles, subjects, etc. This required other tweaks. In C4/Biblio.pm, GetMarcSubjects was returning the subject, even it was supposed to be hidden. C4/XSLT.pm tried to replace a field with no field, rather than properly delete it. With the filtering being implemented based on the parameter style, it just required a minor tweak in opac-ISDBdetail to filter. The title needed to be purposefully not set if it was supposed to be hidden in opac-MARCdetail. However, opac-detail was interesting challenge. First, changing the parameter style did filtering, but the output still was leaking things which should be hidden. This is the main reason ShouldHideMARC was written, because there is an insidious little loop that runs through a set of keys and sets template parameters to values. Second, By skipping to the next key based on the hash ref returned by ShouldHideMARC, the template parameter is not set, and thus the value is properly hidden. Third, the subtitle was grabbed by GetRecordValue. This was refactored so filtering worked properly. Then opac-MARCdetail's 'view plain' was still showing details. This required converting the XML record to a MARC::Record, filtering it, and then converting it back. By tweaking opac-export and opac-showmarc to use the new parameter calling convention, records were filtered properly. And of course, with modifications and additions to C4/Biblio.pm, tests were required. t/Biblio.t has been modified to check the new function ShouldDisplayOnInterface. t/db_dependent/Biblio.t has also been modified. It confirms that both old and new calling conventions work. It also tests hiding the title field (200$a UNIMARC, 245$a MARC). It includes tests for ShouldHideMARC, GetFilteredBiblio, and GetMarcBiblio. TEST PLAN --------- 1) Back up your DB 2) Go to any OPAC detail page and note the biblio number. 3) Log into the staff client and determine the framework code for that biblio number. 4) The steps should be done with OPACXSLTDetailsDisplay set to blank. 5) Home -> Koha administration -> MARC bibliographic framework -> MARC structure (for the matching framework) 6) On the OPAC detail page, click MARC view 7) In the staff client, for every tag listed in the OPAC -> Subfields -> click the first link Then running through all the tabs, click Advanced constraints and uncheck OPAC visibility. Then click Save Changes 8) Refresh the opac-MARCdetail page in OPAC -- what you hid should be mostly hidden TITLE will still display, even if you hide 245$a! 9) Click Normal view, and all the hidden things are still mostly showing! 10) The steps should be done with OPACXSLTDetailsDisplay set to default (or some custom one?). 11) Refresh the opac-detail page. Still mostly showing all the hidden things. 12) Click MARC view, and everything should be mostly hidden as before until you... 13) Click the 'view plain' link. 14) Apply the patch. 15) Run the Koha QA test tool. 16) perldoc C4::Biblio -- Look for ShouldHideMARC and confirm that the perldoc entries are okay. 17) prove -v t/Biblio.t -- 'Visibility values confirmed.' test should pass. 18) prove -v t/db_dependent/Biblio.t -- tests 26 through 41 should pass for UNIMARC and MARC21. It would be good to test this patch on both types of systems. 19) Refresh the opac-MARCdetail page. Title should hide now. 20) Click the 'view plain' link. -- LDR and 999$c and 999$d were displaying for me. I realized that I hadn't hidden 999, because the opac-MARCdetail page doesn't display it. LDR is the only known leak. 21) Click Normal view 22) Now all the opac-detail page should hide things just like the opac-MARCdetail page. 23) In the staff client, change the OPACXSLTDetailsDisplay to a blank value. 24) Recheck opac-detail and opac-MARC detail pages again, including the view plain link, and everything should hidden similarly. -- NOTE: LDR is the only known leak. NOTE: 952 fields do hide in 'MARC view', but not normal view. This patch does not deal with 952 fields. 25) Attempt to 'Save record' in a variety of types. -- Only unhidden fields should display. --- C4/Biblio.pm | 264 +++++++++++++++++++++++++++++++++++++++++++++-- C4/XSLT.pm | 17 +-- opac/opac-ISBDdetail.pl | 5 +- opac/opac-MARCdetail.pl | 3 +- opac/opac-detail.pl | 21 +++- opac/opac-export.pl | 14 ++- opac/opac-showmarc.pl | 13 ++- t/Biblio.t | 27 ++++- t/db_dependent/Biblio.t | 111 +++++++++++++++++++- 9 files changed, 446 insertions(+), 29 deletions(-) diff --git a/C4/Biblio.pm b/C4/Biblio.pm index 5853a52..1e8eb68 100644 --- a/C4/Biblio.pm +++ b/C4/Biblio.pm @@ -77,6 +77,9 @@ BEGIN { &GetMarcISBN &GetMarcISSN &GetMarcSubjects + ShouldDisplayOnInterface + ShouldHideMARC + GetFilteredBiblio &GetMarcBiblio &GetMarcAuthors &GetMarcSeries @@ -1247,22 +1250,163 @@ sub GetMarcSubfieldStructureFromKohaField { return $result; } +sub ShouldDisplayOnInterface { + my $display = { + opac => { + 0 => 1, + -1 => 1, + -2 => 1, + -3 => 1, + -4 => 1, + -5 => 1, + -6 => 1, + -7 => 1, + }, + intranet => { + -6 => 1, + -5 => 1, + -1 => 1, + 0 => 1, + 1 => 1, + 4 => 1, + 6 => 1, + 7 => 1, + }, + }; + return $display; +} + +=head2 ShouldHideMARC + +Return a hash reference of whether a field, built from +kohafield and tag, is hidden (1) or not (0) for a given +interface + + my $OpacHideMARC = + GetOpacHideMARC( { + frameworkcode => $frameworkcode, + interface => 'opac', + } ); + + 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. + +C<$interface> is the interface. It defaults to 'opac' if +nothing is passed. Valid values include 'opac' or 'intranet'. + +=cut + +sub ShouldHideMARC { + my ($parms) = @_; + my $frameworkcode = $parms->{frameworkcode} // ''; + my $interface = $parms->{interface} // 'opac'; + my $display = ShouldDisplayOnInterface(); + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT kohafield AS field, tagfield AS tag, hidden FROM marc_subfield_structure WHERE kohafield>'' AND frameworkcode=? ORDER BY field, tagfield;"); + $sth->execute($frameworkcode); + + my %shouldhidemarc; + my $data = $sth->fetchall_hashref( [ qw(field tag) ] ); + foreach my $fullfield (keys %{$data}) { + my @tmpsplit = split(/\./,$fullfield); + my $field = $tmpsplit[-1]; + foreach my $tag (keys %{$data->{$fullfield}}) { + my $show = $display->{$interface}->{ $data->{$fullfield}->{$tag}->{'hidden'} }; + if (!$show) { + $shouldhidemarc{ $field } = 1; + } + elsif ( !exists($shouldhidemarc{ $field }) ) { + $shouldhidemarc{ $field } = 0; + } + } + } + return \%shouldhidemarc; +} + =head2 GetMarcBiblio - my $record = GetMarcBiblio($biblionumber, [$embeditems]); + my $record = GetMarcBiblio( { + biblionumber => $biblionumber, + embeditems => $embeditems, + interface => 'opac', + frameworkcode => '', + debug => 0, + } ); + +Returns MARC::Record containing biblio data identified by the +parameters passed. + +C<$biblionumber>. If no bib exists, returns undef. This is + required. Otherwise, this returns nothing. -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. + It is optional, and assumed false if omitted. + +C<$interface>. Valid values include 'opac' or 'intranet'. It is + optional. If not passed, no filtering is done. + +C<$framework>. Any valid framework code. By calling this routine + in the hash style, omitting this parameter is + determined by using the biblionumber. If there is + no framework code defined, regardless of calling + convention, the default one is then used. + +C<$debug>. This optional parameter is not defined in the old + calling style, and so it is defaulted to true. + However, if the new hash parameter style is used, + it defaults to false. This was mostly for testing + purposes. See t/db_dependent/Biblio.t and the + warning_is checks. =cut sub GetMarcBiblio { - my $biblionumber = shift; - my $embeditems = shift || 0; - my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? "); + my @catch_parameters = @_; + + my $biblionumber; + my $embeditems; + my $interface; + my $frameworkcode; + my $debug; # This is useful for generating warns for tests. + + # No parameters, return nothing. + if (! @catch_parameters) { + return; + } + # New style means filtering. + elsif (scalar @catch_parameters==1 && ref($catch_parameters[0]) eq 'HASH') { + $biblionumber = $catch_parameters[0]->{biblionumber}; + $embeditems = $catch_parameters[0]->{embeditems}; + $interface = $catch_parameters[0]->{interface}; + $frameworkcode = $catch_parameters[0]->{frameworkcode}; + if (!$frameworkcode && $interface) { + $frameworkcode = GetFrameworkCode($biblionumber); + } + $debug = $catch_parameters[0]->{debug} // 0; + } + # Old style means no filtering. + else { + $biblionumber = shift @catch_parameters if @catch_parameters; + $embeditems = shift @catch_parameters if @catch_parameters; + } + if (! $biblionumber ) { + return; + } + $embeditems //= 0; # No items by default. + $interface //= 'unfiltered'; # unfiltered if no interface passed. + $frameworkcode //= ''; # Default framework if undefined. + $debug //= 1; # Give message for old style calls. + + 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'} ); @@ -1277,12 +1421,114 @@ sub GetMarcBiblio { C4::Biblio::_koha_marc_update_bib_ids($record, '', $biblionumber, $biblionumber); C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems); + # only 'opac' and 'intranet' keys exist, so 'unfiltered' + # won't change anything. + if ($interface ne 'unfiltered') { + $record = GetFilteredBiblio( { + record => $record, + interface => $interface, + frameworkcode => $frameworkcode, + } ); + warn "INTERNAL FILTERING PROCESSED!" if $debug; + + } + else { + warn "INTERNAL FILTERING NOT PROCESSED!" if $debug; + } return $record; } else { return; } } +=head2 GetFilteredBiblio + +Return a MARC::Record which has been filtered based on the +corresponding marc_subfield_structure records for the given +framework and interface ('opac' or 'intranet') + + my $filtered_record = GetFilteredBiblio( { + record => $record, + frameworkcode => $frameworkcode, + interface => 'opac', + } ); + +C<$record> is a MARC::Record. + +C<$frameworkcode> is the framework code. If this is not passed, +the default framework is used. + +C<$interface> is the interface. Valid values include 'opac' and +'intranet' as defined by the hash in ShowDisplayOnInterface. If +this is not passed, 'opac' is used. + +=cut + +sub GetFilteredBiblio { + my ($parms) = @_; + + my $precord = $parms->{record}; + if (!$precord) { + return $precord; + } + my $record = $precord->clone(); + my $interface = $parms->{interface} // 'opac'; + my $frameworkcode = $parms->{frameworkcode} // ''; + my $display = ShouldDisplayOnInterface(); + + 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. + #} + foreach my $field ($record->fields()) { + my $tag = $field->tag(); + if ($tag>=10) { + foreach my $subpairs ($field->subfields()) { + my ($subtag,$value) = @$subpairs; + # visibility is a "level" (-7 to +7), default to 0 + my $visibility = $marcsubfieldstructure->{$tag}->{$subtag}->{hidden}; + $visibility //= 0; + my $hidden; + if ($display->{$interface}->{$visibility}) { + $hidden = 0; + } + else { + $hidden = 1; + } + if ($hidden) { + # deleting last subfield doesn't delete field, so + # this detects that case to delete the field. + if (scalar $field->subfields() <= 1) { + $record->delete_fields($field); + } + else { + $field->delete_subfield( code => $subtag ); + } + } + } + } + # tags less than 10 don't have subfields, use @ trick. + else { + # visibility is a "level" (-7 to +7), default to 0 + my $visibility = $marcsubfieldstructure->{$tag}->{'@'}->{hidden}; + $visibility //= 0; + my $hidden; + if ($display->{$interface}->{$visibility}) { + $hidden = 0; + } + else { + $hidden = 1; + } + if ($hidden) { + $record->delete_fields($field); + } + } + } + return $record; +} + =head2 GetXmlBiblio my $marcxml = GetXmlBiblio($biblionumber); @@ -1867,7 +2113,7 @@ sub GetMarcSubjects { push @marcsubjects, { MARCSUBJECT_SUBFIELDS_LOOP => \@subfields_loop, authoritylink => $authoritylink, - }; + } if $authoritylink || @subfields_loop; } return \@marcsubjects; diff --git a/C4/XSLT.pm b/C4/XSLT.pm index e78343e..c3a128b 100644 --- a/C4/XSLT.pm +++ b/C4/XSLT.pm @@ -85,12 +85,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-ISBDdetail.pl b/opac/opac-ISBDdetail.pl index 2fb7ebc..14b15ad 100755 --- a/opac/opac-ISBDdetail.pl +++ b/opac/opac-ISBDdetail.pl @@ -93,7 +93,10 @@ if (scalar @items >= 1) { } } -my $record = GetMarcBiblio($biblionumber); +my $record = GetMarcBiblio( { + biblionumber => $biblionumber, + interface => 'opac', + } ); 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 f8fab90..b5a5584 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 4b8497c..2bb1c88 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -84,7 +84,10 @@ if (scalar @all_items >= 1) { } } -my $record = GetMarcBiblio($biblionumber); +my $record = GetMarcBiblio( { + biblionumber => $biblionumber, + interface => 'opac', + } ); if ( ! $record ) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); # escape early exit; @@ -518,6 +521,10 @@ if ( C4::Context->preference('HighlightOwnItemsOnOPAC') ) { } my $dat = &GetBiblioData($biblionumber); +my $HideMARC = ShouldHideMARC( { + frameworkcode => $dat->{'frameworkcode'}, + interface => 'opac', + } ); my $itemtypes = GetItemTypes(); # imageurl: @@ -707,7 +714,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 @subtitles; +} +if ($subtitle && @$subtitle) { + my @subtitles = map { { subfield => $_ } } @$subtitle; + $subtitle = \@subtitles; +} $template->param( MARCNOTES => $marcnotesarray, @@ -757,6 +773,7 @@ if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) { } foreach ( keys %{$dat} ) { + next if ( $HideMARC->{$_} ); $template->param( "$_" => defined $dat->{$_} ? $dat->{$_} : '' ); } diff --git a/opac/opac-export.pl b/opac/opac-export.pl index 73e99ec..38cc251 100755 --- a/opac/opac-export.pl +++ b/opac/opac-export.pl @@ -32,9 +32,17 @@ my $op=$query->param("op")||''; #op=export is currently the only use my $format=$query->param("format")||'utf8'; my $biblionumber = $query->param("bib")||0; $biblionumber = int($biblionumber); -my ($marc, $error)= ('',''); +my ($marc, $marc_noitems, $error)= ('','',''); -$marc = GetMarcBiblio($biblionumber, 1) if $biblionumber; +$marc = GetMarcBiblio( { + biblionumber => $biblionumber, + embeditems => 1, + interface => 'opac', + } ) if $biblionumber; +$marc_noitems = GetMarcBiblio( { + biblionumber => $biblionumber, + interface => 'opac', + } ) if $biblionumber; if(!$marc) { print $query->redirect("/cgi-bin/koha/errors/404.pl"); exit; @@ -56,7 +64,7 @@ elsif ($format =~ /ris/) { $format = 'ris'; } elsif ($format =~ /bibtex/) { - $marc = marc2bibtex(C4::Biblio::GetMarcBiblio($biblionumber),$biblionumber); + $marc = marc2bibtex($marc_noitems,$biblionumber); $format = 'bibtex'; } elsif ($format =~ /dc/) { diff --git a/opac/opac-showmarc.pl b/opac/opac-showmarc.pl index 15bbca7..e8a7ebc 100755 --- a/opac/opac-showmarc.pl +++ b/opac/opac-showmarc.pl @@ -44,7 +44,10 @@ if ($importid) { $record = MARC::Record->new_from_usmarc($marc); } else { - $record =GetMarcBiblio($biblionumber); + $record =GetMarcBiblio( { + biblionumber => $biblionumber, + interface => 'opac', + } ); } if(!ref $record) { print $input->redirect("/cgi-bin/koha/errors/404.pl"); @@ -53,6 +56,14 @@ if(!ref $record) { if ($view eq 'card' || $view eq 'html') { my $xml = $importid ? $record->as_xml(): GetXmlBiblio($biblionumber); + if (!$importid && $view eq 'html') { + my $filtered_record = MARC::Record->new_from_xml($xml); + my $frameworkcode = GetFrameworkCode($biblionumber); + $filtered_record = GetFilteredBiblio( { + record => $filtered_record, + frameworkcode => $frameworkcode } ); + $xml = $filtered_record->as_xml(); + } my $xsl = $view eq 'card' ? 'compact.xsl' : 'plainMARC.xsl'; my $htdocs = C4::Context->config('opachtdocs'); my ($theme, $lang) = C4::Templates::themelanguage($htdocs, $xsl, 'opac', $input); diff --git a/t/Biblio.t b/t/Biblio.t index cec30a9..fc37c51 100755 --- a/t/Biblio.t +++ b/t/Biblio.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 44; +use Test::More tests => 45; use Test::MockModule; use Test::Warn; use DBD::Mock; @@ -39,6 +39,31 @@ $context->mock( my @arr; my $ret; +my $display1 = { + opac => { + 0 => 1, + -1 => 1, + -2 => 1, + -3 => 1, + -4 => 1, + -5 => 1, + -6 => 1, + -7 => 1, + }, + intranet => { + -6 => 1, + -5 => 1, + -1 => 1, + 0 => 1, + 1 => 1, + 4 => 1, + 6 => 1, + 7 => 1, + }, + }; +my $display2 = ShouldDisplayOnInterface(); +is_deeply($display2,$display1,'Visibility values confirmed.'); + warning_is { @arr = AddBiblio(undef, q{}) } { carped => 'AddBiblio called with undefined record'}, "AddBiblio returns carped warning on undef record"; diff --git a/t/db_dependent/Biblio.t b/t/db_dependent/Biblio.t index f53b6a5..4463576 100755 --- a/t/db_dependent/Biblio.t +++ b/t/db_dependent/Biblio.t @@ -17,7 +17,8 @@ use Modern::Perl; -use Test::More tests => 4; +use Test::More tests => 8; +use Test::Warn; use Test::MockModule; use MARC::Record; @@ -191,9 +192,96 @@ sub run_tests { "(GetMarcISBN) Corretly retrieves ISBN #". ($i + 1)); } - is( GetMarcPrice( $record_for_isbn, $marcflavour ), 100, "GetMarcPrice returns the correct value"); + + my $unfiltered_record1; + warning_is { $unfiltered_record1 = GetMarcBiblio( $biblionumber ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call1.'; + my $unfiltered_record2; + warning_is { $unfiltered_record2 = GetMarcBiblio( $biblionumber, 0 ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call2.'; + my $unfiltered_record3; + warning_is { $unfiltered_record3 = + GetMarcBiblio( { biblionumber => $biblionumber, + debug => 1 } ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call3.'; + my $unfiltered_record4; + warning_is { $unfiltered_record4 = + GetMarcBiblio( { biblionumber => $biblionumber, + embeditems => 0, + debug => 1 } ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call4.'; + + is_deeply ( $unfiltered_record2, $unfiltered_record1, '(GetMarcBiblio w/o items) old implicitly = old explicitly.'); + is_deeply ( $unfiltered_record3, $unfiltered_record1, '(GetMarcBiblio w/o items) old implicitly = new implicitly.'); + is_deeply ( $unfiltered_record4, $unfiltered_record1, '(GetMarcBiblio w/o items) old implicitly = new explicitly.'); + + warning_is { $unfiltered_record1 = GetMarcBiblio( $biblionumber, 1 ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call5.'; + warning_is { $unfiltered_record2 = + GetMarcBiblio( { biblionumber => $biblionumber, + embeditems => 1, + debug => 1 } ); } + 'INTERNAL FILTERING NOT PROCESSED!', 'GetMarcBiblio Call6.'; + + is_deeply ( $unfiltered_record2, $unfiltered_record1, '(GetMarcBiblio with items) old explicitly = new explicitly.'); + + # the frameworkcode for the added biblio was not set, + # so the frameworkcode is '' for Default. + my $title_field = ( $marcflavour eq 'UNIMARC' ) ? '200' : '245'; + my $sth = $dbh->prepare("SELECT hidden FROM marc_subfield_structure WHERE tagfield='$title_field' and tagsubfield='a' and frameworkcode='';"); + $sth->execute(); + my $hidden = $sth->fetchrow; + if (defined($hidden)) { + ok ( defined($hidden), 'There is a title field entry for the ' . $marcflavour . 'Default framework.'); + + $dbh->do("UPDATE marc_subfield_structure SET hidden=4 WHERE tagfield='$title_field' and tagsubfield='a' and frameworkcode='';"); + $sth = $dbh->prepare("SELECT hidden FROM marc_subfield_structure WHERE tagfield='$title_field' and tagsubfield='a' and frameworkcode='';"); + $sth->execute(); + my $new_hidden = $sth->fetchrow; + ok ( defined($new_hidden) && $new_hidden==4, 'Default framework title field hidden value updated.'); + + # GetFilteredBiblio calls GetMarcStructure which triggers + # caching, this ENV variable is necessary to avoid permission + # denied problems, because normally the cache is owned by + # www-data.www-data and not a git user testing. + $ENV{ MEMCACHED_NAMESPACE } = 'unit_tests'; + my $fail_filter = GetFilteredBiblio(); + ok (!defined($fail_filter), 'GetFilteredBiblio properly handles no parameters.'); + + my $filtered_record1 = GetFilteredBiblio( { + record => $unfiltered_record1 } ); + my $filtered_record2 = GetFilteredBiblio( { + record => $unfiltered_record1, + frameworkcode => '' } ); + my @fields1 = $filtered_record1->fields(); + my @fields2 = $filtered_record2->fields(); + ok ( scalar @fields1 == scalar @fields2, 'No framework code matches Default framework results.'); + + $title = $unfiltered_record1->subfield($title_field,'a'); + my $filtered_title = $filtered_record1->subfield($title_field,'a'); + ok ( defined($title) && !defined($filtered_title), + 'GetFilteredBiblio filtered title as expected. ' . + "title: " . ($title ? $title : "UNDEF") . " -- " . + "hidden: " . ($filtered_title ? $filtered_title : "UNDEF") ); + + $sth = $dbh->prepare("UPDATE marc_subfield_structure SET hidden=? WHERE tagfield='$title_field' and tagsubfield='a' AND frameworkcode='';"); + $sth->execute($hidden); + $sth = $dbh->prepare("SELECT hidden FROM marc_subfield_structure WHERE tagfield='$title_field' and tagsubfield='a' and frameworkcode='';"); + $sth->execute(); + $new_hidden = $sth->fetchrow; + ok ( $new_hidden==$hidden, 'Default framework title field hidden value reset.'); + } + else { + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + ok ( !defined($hidden), 'Skipping tests for MARC field/subfield hiding under ' . $marcflavour . ' Default framework.'); + } + } sub mock_marcfromkohafield { @@ -259,20 +347,33 @@ sub create_issn_field { return $field; } +my $HideMARC = ShouldHideMARC(); +my $keycount1 = keys %$HideMARC; +ok($keycount1>0,"There are $keycount1 values for the Default framework."); + +$HideMARC = ShouldHideMARC({ frameworkcode => 'YOLO' }); +my $keycount2 = keys %$HideMARC; +ok($keycount2==0,'The YOLO framework does not exist.'); + +$HideMARC = ShouldHideMARC({ frameworkcode => '' }); +my $keycount3 = keys %$HideMARC; +ok($keycount1>0,"There are $keycount3 values for the Default framework."); +ok($keycount1==$keycount3,'The no parameter and empty parameter counts match.'); + subtest 'MARC21' => sub { - plan tests => 27; + plan tests => 43; run_tests('MARC21'); $dbh->rollback; }; subtest 'UNIMARC' => sub { - plan tests => 27; + plan tests => 43; run_tests('UNIMARC'); $dbh->rollback; }; subtest 'NORMARC' => sub { - plan tests => 27; + plan tests => 43; run_tests('NORMARC'); $dbh->rollback; }; -- 1.7.9.5