my $dbh=C4::Context->dbh;
return 0, 0 unless $kohafield;
$authtypecode="" unless $authtypecode;
- my $marcfromkohafield;
my $sth = $dbh->prepare("select tagfield,tagsubfield from auth_subfield_structure where kohafield= ? and authtypecode=? ");
$sth->execute($kohafield,$authtypecode);
my ($tagfield,$tagsubfield) = $sth->fetchrow;
sub GetUsedMarcStructure {
my $frameworkcode = shift || '';
- my $query = qq/
+ my $query = q{
SELECT *
FROM marc_subfield_structure
WHERE tab > -1
AND frameworkcode = ?
ORDER BY tagfield, tagsubfield
- /;
+ };
my $sth = C4::Context->dbh->prepare($query);
$sth->execute($frameworkcode);
return $sth->fetchall_arrayref( {} );
}
+=head2 GetMarcSubfieldStructure
+
+=cut
+
+sub GetMarcSubfieldStructure {
+ my ( $frameworkcode ) = @_;
+
+ $frameworkcode //= '';
+
+ my $cache = Koha::Cache->get_instance();
+ my $cache_key = "MarcSubfieldStructure-$frameworkcode";
+ my $cached = $cache->get_from_cache($cache_key);
+ return $cached if $cached;
+
+ my $dbh = C4::Context->dbh;
+ my $subfield_structure = $dbh->selectall_hashref( q|
+ SELECT *
+ FROM marc_subfield_structure
+ WHERE frameworkcode = ?
+ AND kohafield > ''
+ |, 'kohafield', {}, $frameworkcode );
+
+ $cache->set_in_cache( $cache_key, $subfield_structure );
+ return $subfield_structure;
+}
+
=head2 GetMarcFromKohaField
($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode);
=cut
sub GetMarcFromKohaField {
- my $kohafield = shift;
- my $frameworkcode = shift || '';
+ my ( $kohafield, $frameworkcode ) = @_;
return (0, undef) unless $kohafield;
- my $relations = C4::Context->marcfromkohafield;
- if ( my $mf = $relations->{$frameworkcode}->{$kohafield} ) {
- return @$mf;
- }
- return (0, undef);
+ my $mss = GetMarcSubfieldStructure( $frameworkcode );
+ return ( $mss->{$kohafield}{tagfield}, $mss->{$kohafield}{tagsubfield} );
}
=head2 GetMarcSubfieldStructureFromKohaField
=cut
sub GetMarcSubfieldStructureFromKohaField {
- my ($kohafield, $frameworkcode) = @_;
+ my ( $kohafield, $frameworkcode ) = @_;
- return undef unless $kohafield;
- $frameworkcode //= '';
+ return unless $kohafield;
- my $dbh = C4::Context->dbh;
- my $query = qq{
- SELECT *
- FROM marc_subfield_structure
- WHERE kohafield = ?
- AND frameworkcode = ?
- };
- my $sth = $dbh->prepare($query);
- $sth->execute($kohafield, $frameworkcode);
- my $result = $sth->fetchrow_hashref;
- $sth->finish;
-
- return $result;
+ my $mss = GetMarcSubfieldStructure( $frameworkcode );
+ return exists $mss->{$kohafield}
+ ? $mss->{$kohafield}
+ : undef;
}
=head2 GetMarcBiblio
my $hash = shift;
my $record = MARC::Record->new();
SetMarcUnicodeFlag( $record, C4::Context->preference("marcflavour") );
- my $db_to_marc = C4::Context->marcfromkohafield;
+ # FIXME Do not we want to get the marc subfield structure for the biblio framework?
+ my $mss = GetMarcSubfieldStructure();
my $tag_hr = {};
- while ( my ($name, $value) = each %$hash ) {
- next unless my $dtm = $db_to_marc->{''}->{$name};
- next unless ( scalar( @$dtm ) );
- my ($tag, $letter) = @$dtm;
- $tag .= '';
+ while ( my ($kohafield, $value) = each %$hash ) {
+ next unless exists $mss->{$kohafield};
+ next unless $mss->{$kohafield};
+ my $tagfield = $mss->{$kohafield}{tagfield} . '';
+ my $tagsubfield = $mss->{$kohafield}{tagsubfield};
foreach my $value ( split(/\s?\|\s?/, $value, -1) ) {
next if $value eq '';
- $tag_hr->{$tag} //= [];
- push @{$tag_hr->{$tag}}, [($letter, $value)];
+ $tag_hr->{$tagfield} //= [];
+ push @{$tag_hr->{$tagfield}}, [($tagsubfield, $value)];
}
}
foreach my $tag (sort keys %$tag_hr) {
return $record;
}
-# cache inverted MARC field map
-our $inverted_field_map;
-
=head2 TransformMarcToKoha
$result = TransformMarcToKoha( $record, $frameworkcode )
$limit_table = $limit_table || 0;
$frameworkcode = '' unless defined $frameworkcode;
- unless ( defined $inverted_field_map ) {
- $inverted_field_map = _get_inverted_marc_field_map();
- }
+ my $inverted_field_map = _get_inverted_marc_field_map($frameworkcode);
my %tables = ();
if ( defined $limit_table && $limit_table eq 'items' ) {
# traverse through record
MARCFIELD: foreach my $field ( $record->fields() ) {
my $tag = $field->tag();
- next MARCFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag};
+ next MARCFIELD unless exists $inverted_field_map->{$tag};
if ( $field->is_control_field() ) {
- my $kohafields = $inverted_field_map->{$frameworkcode}->{$tag}->{list};
+ my $kohafields = $inverted_field_map->{$tag}->{list};
ENTRY: foreach my $entry ( @{$kohafields} ) {
my ( $subfield, $table, $column ) = @{$entry};
next ENTRY unless exists $tables{$table};
# deal with subfields
MARCSUBFIELD: foreach my $sf ( $field->subfields() ) {
my $code = $sf->[0];
- next MARCSUBFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code};
+ next MARCSUBFIELD unless exists $inverted_field_map->{$tag}->{sfs}->{$code};
my $value = $sf->[1];
- SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code} } ) {
+ SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$tag}->{sfs}->{$code} } ) {
my ( $table, $column ) = @{$entry};
next SFENTRY unless exists $tables{$table};
my $key = _disambiguate( $table, $column );
}
sub _get_inverted_marc_field_map {
+ my ( $frameworkcode ) = @_;
my $field_map = {};
- my $relations = C4::Context->marcfromkohafield;
-
- foreach my $frameworkcode ( keys %{$relations} ) {
- foreach my $kohafield ( keys %{ $relations->{$frameworkcode} } ) {
- next unless @{ $relations->{$frameworkcode}->{$kohafield} }; # not all columns are mapped to MARC tag & subfield
- my $tag = $relations->{$frameworkcode}->{$kohafield}->[0];
- my $subfield = $relations->{$frameworkcode}->{$kohafield}->[1];
- my ( $table, $column ) = split /[.]/, $kohafield, 2;
- push @{ $field_map->{$frameworkcode}->{$tag}->{list} }, [ $subfield, $table, $column ];
- push @{ $field_map->{$frameworkcode}->{$tag}->{sfs}->{$subfield} }, [ $table, $column ];
- }
+ my $mss = GetMarcSubfieldStructure( $frameworkcode );
+
+ foreach my $kohafield ( keys %{ $mss } ) {
+ next unless exists $mss->{$kohafield}; # not all columns are mapped to MARC tag & subfield
+ my $tag = $mss->{$kohafield}{tagfield};
+ my $subfield = $mss->{$kohafield}{tagsubfield};
+ my ( $table, $column ) = split /[.]/, $kohafield, 2;
+ push @{ $field_map->{$tag}->{list} }, [ $subfield, $table, $column ];
+ push @{ $field_map->{$tag}->{sfs}->{$subfield} }, [ $table, $column ];
}
return $field_map;
}
return if !defined($self->{"config"});
$self->{"Zconn"} = undef; # Zebra Connections
- $self->{"marcfromkohafield"} = undef; # the hash with relations between koha table fields and MARC field/subfield
$self->{"userenv"} = undef; # User env
$self->{"activeuser"} = undef; # current active user
$self->{"shelves"} = undef;
return;
}
-=head2 marcfromkohafield
-
- $dbh = C4::Context->marcfromkohafield;
-
-Returns a hash with marcfromkohafield.
-
-This hash is cached for future use: if you call
-C<C4::Context-E<gt>marcfromkohafield> twice, you will get the same hash without real DB access
-
-=cut
-
-#'
-sub marcfromkohafield
-{
- my $retval = {};
-
- # If the hash already exists, return it.
- return $context->{"marcfromkohafield"} if defined($context->{"marcfromkohafield"});
-
- # No hash. Create one.
- $context->{"marcfromkohafield"} = &_new_marcfromkohafield();
-
- return $context->{"marcfromkohafield"};
-}
-
-# _new_marcfromkohafield
-sub _new_marcfromkohafield
-{
- my $dbh = C4::Context->dbh;
- my $marcfromkohafield;
- my $sth = $dbh->prepare("select frameworkcode,kohafield,tagfield,tagsubfield from marc_subfield_structure where kohafield > ''");
- $sth->execute;
- while (my ($frameworkcode,$kohafield,$tagfield,$tagsubfield) = $sth->fetchrow) {
- my $retval = {};
- $marcfromkohafield->{$frameworkcode}->{$kohafield} = [$tagfield,$tagsubfield];
- }
- return $marcfromkohafield;
-}
-
=head2 userenv
C4::Context->userenv;
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
$op = 'list';
} elsif ( $op eq 'delete_confirm' ) {
my $framework = Koha::BiblioFrameworks->find($frameworkcode);
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
$op = 'list';
}
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode");
exit;
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&frameworkcode=$frameworkcode");
exit;
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
}
print $input->redirect("/cgi-bin/koha/admin/marctagstructure.pl?searchfield=$tagfield&frameworkcode=$frameworkcode");
exit;
$cache->clear_from_cache("MarcStructure-0-$frameworkcode");
$cache->clear_from_cache("MarcStructure-1-$frameworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
}
$template->param(
searchfield => $searchfield,
$cache->clear_from_cache("MarcStructure-0-$newframeworkcode");
$cache->clear_from_cache("MarcStructure-1-$newframeworkcode");
$cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
}
$dbh->{AutoCommit} = 0;
$dbh->{RaiseError} = 1;
-# Mocking variables
-my $context = new Test::MockModule('C4::Context');
+subtest 'GetMarcSubfieldStructureFromKohaField' => sub {
+ plan tests => 23;
+
+ my @columns = qw(
+ tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab
+ authorised_value authtypecode value_builder isurl hidden frameworkcode
+ seealso link defaultvalue maxlength
+ );
+
+ # biblio.biblionumber must be mapped so this should return something
+ my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', '');
+
+ ok(defined $marc_subfield_structure, "There is a result");
+ is(ref $marc_subfield_structure, "HASH", "Result is a hashref");
+ foreach my $col (@columns) {
+ ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'");
+ }
+ is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result");
+ like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield");
-mock_marcfromkohafield();
+ # foo.bar does not exist so this should return undef
+ $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', '');
+ is($marc_subfield_structure, undef, "invalid kohafield returns undef");
+};
+
+
+# Mocking variables
+my $biblio_module = new Test::MockModule('C4::Biblio');
+$biblio_module->mock(
+ 'GetMarcSubfieldStructure',
+ sub {
+ my ($self) = shift;
+
+ if ( C4::Context->preference('marcflavour') eq 'MARC21'
+ || C4::Context->preference('marcflavour') eq 'NORMARC' ) {
+
+ return {
+ 'biblio.title' => { tagfield => '245', tagsubfield => 'a' },
+ 'biblio.biblionumber' => { tagfield => '999', tagsubfield => 'c' },
+ 'biblioitems.isbn' => { tagfield => '020', tagsubfield => 'a' },
+ 'biblioitems.issn' => { tagfield => '022', tagsubfield => 'a' },
+ 'biblioitems.biblioitemnumber' => { tagfield => '999', tagsubfield => 'd' },
+ 'items.itemnumber' => { tagfield => '952', tagsubfield => '9' },
+ };
+ } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
+
+ return {
+ 'biblio.title' => { tagfield => '200', tagsubfield => 'a' },
+ 'biblio.biblionumber' => { tagfield => '999', tagsubfield => 'c' },
+ 'biblioitems.isbn' => { tagfield => '010', tagsubfield => 'a' },
+ 'biblioitems.issn' => { tagfield => '011', tagsubfield => 'a' },
+ 'biblioitems.biblioitemnumber' => { tagfield => '090', tagsubfield => 'a' },
+ 'items.itemnumber' => { tagfield => '995', tagsubfield => '9' },
+ };
+ }
+ }
+);
my $currency = new Test::MockModule('Koha::Acquisition::Currencies');
$currency->mock(
sub run_tests {
- # Undef C4::Biblio::inverted_field_map to avoid problems introduced
- # by caching in TransformMarcToKoha
- undef $C4::Biblio::inverted_field_map;
-
my $marcflavour = shift;
t::lib::Mocks::mock_preference('marcflavour', $marcflavour);
'Check the number of returned notes of GetMarcNotes' );
}
-sub mock_marcfromkohafield {
-
- $context->mock('marcfromkohafield',
- sub {
- my ( $self ) = shift;
-
- if ( C4::Context->preference('marcflavour') eq 'MARC21' ||
- C4::Context->preference('marcflavour') eq 'NORMARC' ) {
-
- return {
- '' => {
- 'biblio.title' => [ '245', 'a' ],
- 'biblio.biblionumber' => [ '999', 'c' ],
- 'biblioitems.isbn' => [ '020', 'a' ],
- 'biblioitems.issn' => [ '022', 'a' ],
- 'biblioitems.biblioitemnumber' => [ '999', 'd' ]
- }
- };
- } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
-
- return {
- '' => {
- 'biblio.title' => [ '200', 'a' ],
- 'biblio.biblionumber' => [ '999', 'c' ],
- 'biblioitems.isbn' => [ '010', 'a' ],
- 'biblioitems.issn' => [ '011', 'a' ],
- 'biblioitems.biblioitemnumber' => [ '090', 'a' ]
- }
- };
- }
- });
-}
-
sub create_title_field {
my ( $title, $marcflavour ) = @_;
$dbh->rollback;
};
-subtest 'GetMarcSubfieldStructureFromKohaField' => sub {
- plan tests => 23;
-
- my @columns = qw(
- tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab
- authorised_value authtypecode value_builder isurl hidden frameworkcode
- seealso link defaultvalue maxlength
- );
-
- # biblio.biblionumber must be mapped so this should return something
- my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', '');
-
- ok(defined $marc_subfield_structure, "There is a result");
- is(ref $marc_subfield_structure, "HASH", "Result is a hashref");
- foreach my $col (@columns) {
- ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'");
- }
- is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result");
- like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield");
-
- # foo.bar does not exist so this should return undef
- $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', '');
- is($marc_subfield_structure, undef, "invalid kohafield returns undef");
-};
-
subtest 'IsMarcStructureInternal' => sub {
plan tests => 6;
my $tagslib = GetMarcStructure();
}
ok($found, "item1 found");
- my ($itemfield) = GetMarcFromKohaField('items.itemnumber', '');
+ my $frameworkcode = q||;
+ my ($itemfield) = GetMarcFromKohaField('items.itemnumber', $frameworkcode);
# Create item subfield 'z' without link
- $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield);
- $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", "")', undef, $itemfield);
+ $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
+ $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", ?)', undef, $itemfield, $frameworkcode);
# Clear cache
- $C4::Context::context->{marcfromkohafield} = undef;
- $C4::Biblio::inverted_field_map = undef;
+ my $cache = Koha::Cache->get_instance();
+ $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
+ $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
+ $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
my $item3_record = new MARC::Record;
$item3_record->append_fields(
# Link $z to items.itemnotes (and make sure there is no other subfields
# linked to it)
- $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=""', undef, $itemfield);
- $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield);
+ $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
+ $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
# Clear cache
- $C4::Context::context->{marcfromkohafield} = undef;
- $C4::Biblio::inverted_field_map = undef;
+ $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
+ $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
+ $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+ $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
ModItemFromMarc($item3_record, $biblionumber, $item3_itemnumber);
$schema->storage->txn_begin();
- # Clear cache
- $C4::Context::context->{marcfromkohafield} = undef;
- $C4::Biblio::inverted_field_map = undef;
-
my $builder = t::lib::TestBuilder->new;
my $framework = $builder->build({
source => 'BiblioFramework',
|, undef, $framework->{frameworkcode} );
# And make sure the caches are cleared
- $C4::Context::context->{marcfromkohafield} = undef;
- $C4::Biblio::inverted_field_map = undef;
- my $cache = Koha::Cache->get_instance();
- $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode} );
+ my $cache = Koha::Cache->get_instance();
+ $cache->clear_from_cache("MarcStructure-0-" . $framework->{frameworkcode});
+ $cache->clear_from_cache("MarcStructure-1-" . $framework->{frameworkcode});
+ $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode});
+ $cache->clear_from_cache("MarcSubfieldStructure-" . $framework->{frameworkcode});
# Update the MARC field with another value
$item_record->delete_fields( $barcode_field );