From 1492640cd79a8d3d5e3f4758102db067b38097b8 Mon Sep 17 00:00:00 2001 From: Mark Tompsett Date: Mon, 6 Jun 2016 15:07:06 -0400 Subject: [PATCH] Bug 16335: Refactor OpacHiddenItems This creates a filter and adds a test file for that filter. TEST PLAN --------- 1) apply patch 2) prove t/db_dependent/Filter_MARC_OpacHiddenItems.t 3) run koha qa test tools NOTE: I'd ignore the only once warnings. https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=16104#c18 --- Koha/Filter/MARC/OpacHiddenItems.pm | 224 +++++++++++++++++++++++++++ t/db_dependent/Filter_MARC_OpacHiddenItems.t | 141 +++++++++++++++++ 2 files changed, 365 insertions(+) create mode 100644 Koha/Filter/MARC/OpacHiddenItems.pm create mode 100644 t/db_dependent/Filter_MARC_OpacHiddenItems.t diff --git a/Koha/Filter/MARC/OpacHiddenItems.pm b/Koha/Filter/MARC/OpacHiddenItems.pm new file mode 100644 index 0000000..6f90fdd --- /dev/null +++ b/Koha/Filter/MARC/OpacHiddenItems.pm @@ -0,0 +1,224 @@ +package Koha::Filter::MARC::OpacHiddenItems; + +# Copyright 2016 Mark Tompsett +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +=head1 NAME + +Koha::Filter::MARC::OpacHiddenItems - this filters a MARC record. + +=head1 VERSION + +version 1.0 + +=head1 SYNOPSIS + +my $processor = Koha::RecordProcessor->new( { filters => ('OpacHiddenItems') } ); + +=head1 DESCRIPTION + +Filter to remove fields based on the OPAC system preference OpacHiddenItems. + +=cut + +use C4::Biblio; +use Carp; +use Const::Fast; +use English qw( -no_match_vars ); +use List::Util qw/any/; +use Modern::Perl; +use YAML; + +use base qw(Koha::RecordProcessor::Base); + +our $NAME = 'MARC_OpacHiddenItems'; +our $VERSION = '3.25'; # Master version I hope it gets in. + +const my $FIRST_NONCONTROL_TAG => 10; # tags < 10 are control tags. + +=head1 SUBROUTINES/METHODS + +=head2 filter + + my $processor = Koha::RecordProcessor->new( { filters => ('OpacHiddenItems') } ); +... + my $newrecord = $processor->filter($record); + my $newrecords = $processor->filter(\@records); + +This returns a filtered copy of the record based on the Advanced constraints +visibility settings. + +=cut + +sub filter { + my $self = shift; + my $precord = shift; + my @records; + + if ( !$precord ) { + return $precord; + } + + if ( ref($precord) eq 'ARRAY' ) { + @records = @{$precord}; + } + else { + push @records, $precord; + } + + my $yaml = C4::Context->preference('OpacHiddenItems'); + return () if ( !$yaml =~ /\S/xsm ); + $yaml = "$yaml\n\n"; # YAML is anal on ending \n. Surplus does not hurt + my $hidingrules; + my $return_value = eval { $hidingrules = YAML::Load($yaml); }; + if ( $EVAL_ERROR || !$return_value ) { + carp +"Unable to parse OpacHiddenItems syspref : $EVAL_ERROR ($return_value)"; + return; + } + my $dbh = C4::Context->dbh; + + foreach my $current_record (@records) { + my $biblionumber = + C4::Biblio::get_koha_field_from_marc( 'biblio', 'biblionumber', + $current_record, q{} ); + my $frameworkcode = q{}; + if ( defined $biblionumber ) { + my $biblio = GetBiblio($biblionumber); + $frameworkcode = $biblio->{'frameworkcode'} // q{}; + } + _filter_record( $hidingrules, $current_record, $frameworkcode ); + } + return; +} + +sub _filter_record { + my ( $hidingrules, $current_record, $frameworkcode ) = @_; + + my $dbh = C4::Context->dbh; + + # items are all on a specific tag. + my $itemtag = $dbh->selectrow_array( + 'SELECT DISTINCT tagfield FROM marc_subfield_structure ' + . q{WHERE kohafield LIKE 'items.%' ORDER BY tagfield} + ); + if (! defined $itemtag) { + return; + } + + # Run through the MARC record's fields... + my @fields = $current_record->fields(); + foreach my $field (@fields) { + + # Skip everything except item fields. + my $tag = $field->tag(); + if ($tag ne $itemtag) { + next; + } + + my @subfields = $field->subfields(); + foreach my $subfield (@subfields) { + + # determine it's tag, subtag, and value. + my $subtag = $subfield->[0]; + my $value = $subfield->[1]; + + # find the matching kohafield, if it is in items + my @params = ( $tag, $subtag ); + my $kohafield = $dbh->selectrow_array( + 'SELECT kohafield FROM marc_subfield_structure ' + . q{WHERE kohafield LIKE 'items.%' AND } + . 'tagfield=? and tagsubfield=?', + undef, @params + ); + + # if there is a corresponding items kohafield... + if ( defined $kohafield ) { + $kohafield =~ s/items.//xsmg; + + # Check it against what is supposed to be hidden. + if ( any { $value eq $_ } @{ $hidingrules->{$kohafield} } ) { + + $current_record->delete_field($field); + last; + } + } + } + } + return; +} + +sub initialize { + my $self = shift; + my $param = shift; + + my $options = $param->{options}; + $self->{options} = $options; + $self->Koha::RecordProcessor::Base::initialize($param); + return; +} + +=head1 DIAGNOSTICS + + $ prove -v t/RecordProcessor.t + $ prove -v t/db_dependent/Filter_MARC_OpacHiddenItems.t + +=head1 CONFIGURATION AND ENVIRONMENT + +Install Koha. This filter will be used appropriately by the OPAC or Staff client. + +=head1 INCOMPATIBILITIES + +This is designed for MARC::Record filtering currently. It will not handle MARC::MARCXML. + +=head1 DEPENDENCIES + +The following Perl libraries are required: Modern::Perl and Carp. +The following Koha libraries are required: C4::Biblio, Koha::RecordProcessor, and Koha::RecordProcessor::Base. +These should all be installed if the koha-common package is installed or Koha is otherwise installed. + +=head1 BUGS AND LIMITATIONS + +This is the initial version. Please feel free to report bugs +at http://bugs.koha-community.org/. + +=head1 AUTHOR + +Mark Tompsett + +=head1 LICENSE AND COPYRIGHT + +Copyright 2016 Mark Tompsett + +This file is part of Koha. + +Koha is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Koha is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Koha; if not, see . + +=cut + +1; diff --git a/t/db_dependent/Filter_MARC_OpacHiddenItems.t b/t/db_dependent/Filter_MARC_OpacHiddenItems.t new file mode 100644 index 0000000..ed85c74 --- /dev/null +++ b/t/db_dependent/Filter_MARC_OpacHiddenItems.t @@ -0,0 +1,141 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Copyright 2015 Mark Tompsett +# - Initial commit, perlcritic clean-up, and +# debugging +# Copyright 2016 Tomas Cohen Arazi +# - Expansion of test cases to be comprehensive +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 4; + +use List::MoreUtils qw/any/; +use MARC::Record; +use MARC::Field; +use C4::Context; +use C4::Biblio; +use Koha::Cache qw/flush_all/; +use Koha::Database; + +BEGIN { + use_ok('Koha::RecordProcessor'); +} + +my $dbh = C4::Context->dbh; + +my $database = Koha::Database->new(); +my $schema = $database->schema(); +$dbh->{RaiseError} = 1; + +sub run_hiding_tests { + + my $cache = Koha::Cache->get_instance(); + $cache->flush_all(); # easy way to ensure DB is queried again. + + my $processor = Koha::RecordProcessor->new( + { + schema => 'MARC', + filters => ('OpacHiddenItems') + } + ); + + is( + ref( $processor->filters->[0] ), + 'Koha::Filter::MARC::OpacHiddenItems', + 'Created record processor with OpacHiddenItems filter' + ); + + # Create a fresh record + my $sample_record = create_marc_record(); + my $unfiltered_record = $sample_record->clone(); + + # Apply filters + my $filtered_record = $processor->process($sample_record); + + # Data fields + my $opac_hidden_items = C4::Context->preference('OpacHiddenItems'); + if ( $opac_hidden_items eq q{} ) { + is_deeply( $unfiltered_record, $filtered_record, + 'No filtering is unfiltered.' ); + } + elsif ( $opac_hidden_items =~ /BARCODE2/xsm ) { + is_deeply( $unfiltered_record, $filtered_record, + 'Mismatched filtering is unfiltered.' ); + } + else { + my ( $barcode_tag, $barcode_subtag ) = + GetMarcFromKohaField( 'items.barcode', q{} ); + my $value = $filtered_record->subfield( $barcode_tag, $barcode_subtag ); + ok( !defined $value, 'Filtered subfield is hidden.' ); + } + return; +} + +sub create_marc_record { + + my ( $title_field, $title_subfield ) = + GetMarcFromKohaField( 'biblio.title', q{} ); + my ( $isbn_field, $isbn_subfield ) = + GetMarcFromKohaField( 'biblioitems.isbn', q{} ); + my ( $bc_tag, $bc_subtag ) = GetMarcFromKohaField( 'items.barcode', q{} ); + my $isbn = '0590353403'; + my $title = 'Foundation'; + my $barcode = 'BARCODE1'; + my $marc_record = MARC::Record->new; + my @fields = ( + MARC::Field->new( '003', 'AR-CdUBM' ), + MARC::Field->new( '008', '######suuuu####ag_||||__||||_0||_|_uuu|d' ), + MARC::Field->new( $isbn_field, q{}, q{}, $isbn_subfield => $isbn ), + MARC::Field->new( $title_field, q{}, q{}, $title_subfield => $title ), + MARC::Field->new( $bc_tag, q{}, q{}, $bc_subtag => $barcode ), + ); + + $marc_record->insert_fields_ordered(@fields); + + return $marc_record; +} + +subtest 'Koha::Filter::MARC::OpacHiddenItem hide rules match' => sub { + plan tests => 2; + + $schema->storage->txn_begin(); + C4::Context->set_preference( 'OpacHiddenItems', "barcode: [BARCODE1]\n\n" ); + run_hiding_tests; + $schema->storage->txn_rollback(); +}; + +subtest 'Koha::Filter::MARC::OpacHiddenItem show with rules' => sub { + plan tests => 2; + + $schema->storage->txn_begin(); + C4::Context->set_preference( 'OpacHiddenItems', "barcode: [BARCODE2]\n\n" ); + run_hiding_tests; + $schema->storage->txn_rollback(); +}; + +subtest 'Koha::Filter::MARC::OpacHiddenItem show with no rules' => sub { + plan tests => 2; + + $schema->storage->txn_begin(); + C4::Context->set_preference( 'OpacHiddenItems', q{} ); + run_hiding_tests; + $schema->storage->txn_rollback(); +}; + +1; -- 2.1.4