From 9e03102a77e1814c3c23801bd823a1ed84686764 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 12 May 2020 14:06:27 +0000 Subject: [PATCH] Bug 25467: Build and cache hidden fields and use them for filtering --- Koha/Filter/MARC/ViewPolicy.pm | 88 +++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/Koha/Filter/MARC/ViewPolicy.pm b/Koha/Filter/MARC/ViewPolicy.pm index 4d7adfdf67..775d053397 100644 --- a/Koha/Filter/MARC/ViewPolicy.pm +++ b/Koha/Filter/MARC/ViewPolicy.pm @@ -89,21 +89,27 @@ sub filter { unless ( exists $self->{_cached_frameworks}->{$frameworkcode} ) { $self->{_cached_frameworks}->{$frameworkcode} = GetMarcStructure( 0, $frameworkcode, { unsafe => 1 } ); } - my $marcsubfieldstructure = $self->{_cached_frameworks}->{$frameworkcode}; + unless ( exists $self->{_cached_hidden_fields}->{$frameworkcode}->{$interface} ){ + $self->{_cached_hidden_fields}->{$frameworkcode}->{$interface} = + _get_hidden_fields_from_framework({ + marcsubfieldstructure => $marcsubfieldstructure, + hide => $hide, + interface => $interface, + }); + } + my $hidden_fields = $self->{_cached_hidden_fields}->{$frameworkcode}->{$interface}; #if ($marcsubfieldstructure->{'000'}->{'@'}->{hidden}>0) { # LDR field is excluded from $current_record->fields(). # if we hide it here, the MARCXML->MARC::Record->MARCXML # transformation blows up. #} - foreach my $field ( $result->fields() ) { + foreach my $field ( keys %{$hidden_fields} ) { _filter_field( { field => $field, - marcsubfieldstructure => $marcsubfieldstructure, - hide => $hide, - interface => $interface, + subfields => $hidden_fields->{$field}, result => $result } ); @@ -112,50 +118,62 @@ sub filter { return; } -sub _filter_field { - my ($parameter) = @_; - - my $field = $parameter->{field}; - my $marcsubfieldstructure = $parameter->{marcsubfieldstructure}; - my $hide = $parameter->{hide}; - my $interface = $parameter->{interface}; - my $result = $parameter->{result}; - - my $tag = $field->tag(); - if ( $tag >= FIRST_NONCONTROL_TAG ) { - foreach my $subpairs ( $field->subfields() ) { - my ( $subtag, $value ) = @{$subpairs}; - +sub _get_hidden_fields_from_framework { + my ($params) = @_; + my $mss = $params->{marcsubfieldstructure}; + my $interface = $params->{interface}; + my $hide = $params->{hide}; + my $hidden_fields; + foreach my $tag (keys %{$mss}) { + if ( $tag >= FIRST_NONCONTROL_TAG ) { + foreach my $subtag (keys %{$mss->{$tag}}) { + next unless ref $mss->{$tag}->{$subtag} eq 'HASH'; + my $visibility = $mss->{$tag}->{$subtag}->{hidden}; + $visibility //= 0; + if( $hide->{$interface}->{$visibility}){ + $hidden_fields->{$tag}->{$subtag} = 1; + } + } + } else { # visibility is a "level" (-9 to +9), default to 0 # -8 is flagged, and 9/-9 are not implemented. - my $visibility = - $marcsubfieldstructure->{$tag}->{$subtag}->{hidden}; + my $visibility = $mss->{$tag}->{q{@}}->{hidden}; $visibility //= 0; if ( $hide->{$interface}->{$visibility} ) { + $hidden_fields->{$tag}->{q{@}} = 1; + } + } + } + return $hidden_fields; +} + + +sub _filter_field { + my ($parameter) = @_; + my $field = $parameter->{field}; + my $subfields = $parameter->{subfields}; + my $result = $parameter->{result}; + + my @result_fields = $result->field($field); + return unless @result_fields; + foreach my $result_field ( @result_fields ){ + if ( $field >= FIRST_NONCONTROL_TAG ) { + foreach my $subfield ( keys %{$subfields}) { # deleting last subfield doesn't delete field, so # this detects that case to delete the field. - if ( scalar $field->subfields() <= 1 ) { - $result->delete_fields($field); + if ( scalar $result_field->subfields() <= 1 ) { + $result->delete_fields($result_field); } else { - $field->delete_subfield( code => $subtag ); + $result_field->delete_subfield( code => $subfield ); } } + } else { + $result->delete_fields($result_field); } } - # control tags don't have subfields, use @ trick. - else { - # visibility is a "level" (-9 to +9), default to 0 - # -8 is flagged, and 9/-9 are not implemented. - my $visibility = $marcsubfieldstructure->{$tag}->{q{@}}->{hidden}; - $visibility //= 0; - if ( $hide->{$interface}->{$visibility} ) { - $result->delete_fields($field); - } - - } return; } -- 2.11.0