use C4::Dates qw/format_date/;
use C4::Log; # logaction
use C4::ClassSource;
-use C4::Heading;
+use C4::Charset;
use vars qw($VERSION @ISA @EXPORT);
);
}
+# because of interdependencies between
+# C4::Search, C4::Heading, and C4::Biblio,
+# 'use C4::Heading' must occur after
+# the exports have been defined.
+use C4::Heading;
+
=head1 NAME
C4::Biblio - cataloging management functions
_koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
+ # update MARC subfield that stores biblioitems.cn_sort
+ _koha_marc_update_biblioitem_cn_sort($record, $olddata, $frameworkcode);
+
# now add the record
$biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode ) unless $defer_marc_save;
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","ADD",$biblionumber,"biblio")
- if C4::Context->preference("CataloguingLog");
+ logaction("CATALOGUING", "ADD", $biblionumber, "biblio") if C4::Context->preference("CataloguingLog");
return ( $biblionumber, $biblioitemnumber );
}
=head2 ModBiblio
+=over 4
+
ModBiblio( $record,$biblionumber,$frameworkcode);
- Exported function (core API) to modify a biblio
+
+=back
+
+Replace an existing bib record identified by C<$biblionumber>
+with one supplied by the MARC::Record object C<$record>. The embedded
+item, biblioitem, and biblionumber fields from the previous
+version of the bib record replace any such fields of those tags that
+are present in C<$record>. Consequently, ModBiblio() is not
+to be used to try to modify item records.
+
+C<$frameworkcode> specifies the MARC framework to use
+when storing the modified bib record; among other things,
+this controls how MARC fields get mapped to display columns
+in the C<biblio> and C<biblioitems> tables, as well as
+which fields are used to store embedded item, biblioitem,
+and biblionumber data for indexing.
=cut
my ( $record, $biblionumber, $frameworkcode ) = @_;
if (C4::Context->preference("CataloguingLog")) {
my $newrecord = GetMarcBiblio($biblionumber);
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","MODIFY",$biblionumber,"BEFORE=>".$newrecord->as_formatted);
+ logaction("CATALOGUING", "MODIFY", $biblionumber, "BEFORE=>".$newrecord->as_formatted);
}
my $dbh = C4::Context->dbh;
# get the items before and append them to the biblio before updating the record, atm we just have the biblio
my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
my $oldRecord = GetMarcBiblio( $biblionumber );
+
+ # delete any item fields from incoming record to avoid
+ # duplication or incorrect data - use AddItem() or ModItem()
+ # to change items
+ foreach my $field ($record->field($itemtag)) {
+ $record->delete_field($field);
+ }
# parse each item, and, for an unknown reason, re-encode each subfield
# if you don't do that, the record will have encoding mixed
$sth->finish();
_koha_marc_update_bib_ids($record, $frameworkcode, $biblionumber, $biblioitemnumber);
- # update the MARC record (that now contains biblio and items) with the new record data
- &ModBiblioMarc( $record, $biblionumber, $frameworkcode );
-
# load the koha-table data object
my $oldbiblio = TransformMarcToKoha( $dbh, $record, $frameworkcode );
+ # update MARC subfield that stores biblioitems.cn_sort
+ _koha_marc_update_biblioitem_cn_sort($record, $oldbiblio, $frameworkcode);
+
+ # update the MARC record (that now contains biblio and items) with the new record data
+ &ModBiblioMarc( $record, $biblionumber, $frameworkcode );
+
# modify the other koha tables
_koha_modify_biblio( $dbh, $oldbiblio, $frameworkcode );
_koha_modify_biblioitem_nonmarc( $dbh, $oldbiblio );
# - we need to read the biblio if NoZebra is set (to remove it from the indexes
# - if something goes wrong, the biblio may be deleted from Koha but not from zebra
# and we would have no way to remove it (except manually in zebra, but I bet it would be very hard to handle the problem)
- ModZebra($biblionumber, "recordDelete", "biblioserver", undef);
+ my $oldRecord;
+ if (C4::Context->preference("NoZebra")) {
+ # only NoZebra indexing needs to have
+ # the previous version of the record
+ $oldRecord = GetMarcBiblio($biblionumber);
+ }
+ ModZebra($biblionumber, "recordDelete", "biblioserver", $oldRecord, undef);
# delete biblioitems and items from Koha tables and save in deletedbiblioitems,deleteditems
$sth =
# from being generated by _koha_delete_biblioitems
$error = _koha_delete_biblio( $dbh, $biblionumber );
- &logaction(C4::Context->userenv->{'number'},"CATALOGUING","DELETE",$biblionumber,"")
- if C4::Context->preference("CataloguingLog");
+ logaction("CATALOGUING", "DELETE", $biblionumber, "") if C4::Context->preference("CataloguingLog");
+
return;
}
{
$res->{$tag}->{lib} =
( $forlibrarian or !$libopac ) ? $liblibrarian : $libopac;
- $res->{$tab}->{tab} = "";
+ $res->{$tag}->{tab} = "";
$res->{$tag}->{mandatory} = $mandatory;
$res->{$tag}->{repeatable} = $repeatable;
}
=over 4
-Returns MARC::Record of the biblionumber passed in parameter.
-the marc record contains both biblio & item datas
+my $record = GetMarcBiblio($biblionumber);
=back
+Returns MARC::Record representing bib identified by
+C<$biblionumber>. If no bib exists, returns undef.
+The MARC record contains both biblio & item data.
+
=cut
sub GetMarcBiblio {
my $sth =
$dbh->prepare("SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
$sth->execute($biblionumber);
- my ($marcxml) = $sth->fetchrow;
+ my $row = $sth->fetchrow_hashref;
+ my $marcxml = StripNonXmlChars($row->{'marcxml'});
MARC::File::XML->default_record_format(C4::Context->preference('marcflavour'));
- $marcxml =~ s/\x1e//g;
- $marcxml =~ s/\x1f//g;
- $marcxml =~ s/\x1d//g;
- $marcxml =~ s/\x0f//g;
- $marcxml =~ s/\x0c//g;
-# warn $marcxml;
my $record = MARC::Record->new();
if ($marcxml) {
$record = eval {MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour'))};
my $subfield9 = $field->subfield('9');
for my $subject_subfield (@subfields ) {
# don't load unimarc subfields 3,4,5
- next if (($marcflavour eq "UNIMARC") and ($subject_subfield->[0] =~ (3|4|5) ) );
+ next if (($marcflavour eq "UNIMARC") and ($subject_subfield->[0] =~ /3|4|5/ ) );
my $code = $subject_subfield->[0];
my $value = $subject_subfield->[1];
my $linkvalue = $value;
my $separator = C4::Context->preference("authoritysep") unless $counter==0;
# ignore $9
my @this_link_loop = @link_loop;
- push @subfields_loop, {code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator} unless ($subject_subfield->[0] == 9 );
+ push @subfields_loop, {code => $code, value => $value, link_loop => \@this_link_loop, separator => $separator} unless ($subject_subfield->[0] eq 9 );
$counter++;
}
my $subfield9 = $field->subfield('9');
for my $authors_subfield (@subfields) {
# don't load unimarc subfields 3, 5
- next if ($marcflavour eq 'UNIMARC' and ($authors_subfield->[0] =~ (3|5) ) );
+ next if ($marcflavour eq 'UNIMARC' and ($authors_subfield->[0] =~ /3|5/ ) );
my $subfieldcode = $authors_subfield->[0];
my $value = $authors_subfield->[1];
my $linkvalue = $value;
my $operator = " and " unless $count_auth==0;
# if we have an authority link, use that as the link, otherwise use standard searching
if ($subfield9) {
- @link_loop = ({'limit' => 'Koha-Auth-Number' ,link => "$subfield9" });
+ @link_loop = ({'limit' => 'an' ,link => "$subfield9" });
}
else {
# reset $linkvalue if UNIMARC author responsibility
for my $note ( $field->subfield('z')) {
push @notes , {note => $note};
}
- $marcurl = { MARCURL => $url,
- notes => \@notes,
- };
if($marcflavour eq 'MARC21') {
my $s3 = $field->subfield('3');
my $link = $field->subfield('y');
- $marcurl->{'linktext'} = $link || $s3 || $url ;;
+ unless($url =~ /^\w+:/) {
+ if($field->indicator(1) eq '7') {
+ $url = $field->subfield('2') . "://" . $url;
+ } elsif ($field->indicator(1) eq '1') {
+ $url = 'ftp://' . $url;
+ } else {
+ # properly, this should be if ind1=4,
+ # however we will assume http protocol since we're building a link.
+ $url = 'http://' . $url;
+ }
+ }
+ # TODO handle ind 2 (relationship)
+ $marcurl = { MARCURL => $url,
+ notes => \@notes,
+ };
+ $marcurl->{'linktext'} = $link || $s3 || C4::Context->preference('URLLinkText') || $url ;;
$marcurl->{'part'} = $s3 if($link);
$marcurl->{'toc'} = 1 if($s3 =~ /^[Tt]able/) ;
} else {
- $marcurl->{'linktext'} = $url;
+ $marcurl->{'linktext'} = $url || C4::Context->preference('URLLinkText') ;
}
push @marcurls, $marcurl;
}
L<$record> = TransformHtmlToMarc(L<$params>,L<$cgi>)
L<$params> is a ref to an array as below:
{
- 'tag_010_indicator_531951' ,
+ 'tag_010_indicator1_531951' ,
+ 'tag_010_indicator2_531951' ,
'tag_010_code_a_531951_145735' ,
'tag_010_subfield_a_531951_145735' ,
- 'tag_200_indicator_873510' ,
+ 'tag_200_indicator1_873510' ,
+ 'tag_200_indicator2_873510' ,
'tag_200_code_a_873510_673465' ,
'tag_200_subfield_a_873510_673465' ,
'tag_200_code_b_873510_704318' ,
sub TransformHtmlToMarc {
my $params = shift;
my $cgi = shift;
-
+
+ # explicitly turn on the UTF-8 flag for all
+ # 'tag_' parameters to avoid incorrect character
+ # conversion later on
+ my $cgi_params = $cgi->Vars;
+ foreach my $param_name (keys %$cgi_params) {
+ if ($param_name =~ /^tag_/) {
+ my $param_value = $cgi_params->{$param_name};
+ if (utf8::decode($param_value)) {
+ $cgi_params->{$param_name} = $param_value;
+ }
+ # FIXME - need to do something if string is not valid UTF-8
+ }
+ }
+
# creating a new record
my $record = MARC::Record->new();
my $i=0;
}
push @fields,$newfield if($newfield);
}
- elsif ($param =~ /^tag_(\d*)_indicator_/){ # new field start when having 'input name="..._indicator_..."
+ elsif ($param =~ /^tag_(\d*)_indicator1_/){ # new field start when having 'input name="..._indicator1_..."
my $tag = $1;
my $ind1 = substr($cgi->param($param),0,1);
- my $ind2 = substr($cgi->param($param),1,1);
+ my $ind2 = substr($cgi->param($params->[$i+1]),0,1);
$newfield=0;
- my $j=$i+1;
+ my $j=$i+2;
if($tag < 10){ # no code for theses fields
# in MARC editor, 000 contains the leader.
if ($tag eq '000' ) {
$record->leader($cgi->param($params->[$j+1])) if length($cgi->param($params->[$j+1]))==24;
# between 001 and 009 (included)
- } else {
+ } elsif ($cgi->param($params->[$j+1]) ne '') {
$newfield = MARC::Field->new(
$tag,
$cgi->param($params->[$j+1]),
while($params->[$j] =~ /_code_/){ # browse all it's subfield
my $inner_param = $params->[$j];
if ($newfield){
- if($cgi->param($params->[$j+1])){ # only if there is a value (code => value)
+ if($cgi->param($params->[$j+1]) ne ''){ # only if there is a value (code => value)
$newfield->add_subfields(
$cgi->param($inner_param) => $cgi->param($params->[$j+1])
);
}
} else {
- if ( $cgi->param($params->[$j+1]) ) { # creating only if there is a value (code => value)
+ if ( $cgi->param($params->[$j+1]) ne '' ) { # creating only if there is a value (code => value)
$newfield = MARC::Field->new(
$tag,
''.$ind1,
sub PrepareItemrecordDisplay {
- my ( $bibnum, $itemnum ) = @_;
+ my ( $bibnum, $itemnum, $defaultvalues ) = @_;
my $dbh = C4::Context->dbh;
my $frameworkcode = &GetFrameworkCode( $bibnum );
$tagslib->{$tag}->{$subfield}->{'kohafield'};
# $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib};
- $subfield_data{marc_lib} =
- "<span id=\"error\" title=\""
- . $tagslib->{$tag}->{$subfield}->{lib} . "\">"
- . substr( $tagslib->{$tag}->{$subfield}->{lib}, 0, 12 )
- . "</span>";
+ $subfield_data{marc_lib} = $tagslib->{$tag}->{$subfield}->{lib};
$subfield_data{mandatory} =
$tagslib->{$tag}->{$subfield}->{mandatory};
$subfield_data{repeatable} =
$value = $temp->subfield($CNsubfield);
}
}
+ if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq
+ 'items.itemcallnumber'
+ && $defaultvalues->{'callnumber'} )
+ {
+ my $temp = $itemrecord->field($subfield) if ($itemrecord);
+ unless ($temp) {
+ $value = $defaultvalues->{'callnumber'};
+ }
+ }
+ if ( ($tagslib->{$tag}->{$subfield}->{kohafield} eq
+ 'items.holdingbranch' ||
+ $tagslib->{$tag}->{$subfield}->{kohafield} eq
+ 'items.homebranch')
+ && $defaultvalues->{'branchcode'} )
+ {
+ my $temp = $itemrecord->field($subfield) if ($itemrecord);
+ unless ($temp) {
+ $value = $defaultvalues->{branchcode};
+ }
+ }
if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
my @authorised_values;
my %authorised_lib;
}
elsif ( $tagslib->{$tag}->{$subfield}->{thesaurus_category} ) {
$subfield_data{marc_value} =
-"<input type=\"text\" name=\"field_value\" size=47 maxlength=255> <a href=\"javascript:Dopop('cataloguing/thesaurus_popup.pl?category=$tagslib->{$tag}->{$subfield}->{thesaurus_category}&index=',)\">...</a>";
+"<input type=\"text\" name=\"field_value\" size=\"47\" maxlength=\"255\" /> <a href=\"javascript:Dopop('cataloguing/thesaurus_popup.pl?category=$tagslib->{$tag}->{$subfield}->{thesaurus_category}&index=',)\">...</a>";
#"
# COMMENTED OUT because No $i is provided with this API.
}
else {
$subfield_data{marc_value} =
-"<input type=\"text\" name=\"field_value\" value=\"$value\" size=50 maxlength=255>";
+"<input type=\"text\" name=\"field_value\" value=\"$value\" size=\"50\" maxlength=\"255\" />";
}
push( @loop_data, \%subfield_data );
}
=over 4
-ModZebra( $biblionumber, $op, $server, $newRecord );
+ModZebra( $biblionumber, $op, $server, $oldRecord, $newRecord );
$biblionumber is the biblionumber we want to index
$op is specialUpdate or delete, and is used to know what we want to do
$server is the server that we want to update
+ $oldRecord is the MARC::Record containing the previous version of the record. This is used only when
+ NoZebra=1, as NoZebra indexing needs to know the previous version of a record in order to
+ do an update.
$newRecord is the MARC::Record containing the new record. It is usefull only when NoZebra=1, and is used to know what to add to the nozebra database. (the record in mySQL being, if it exist, the previous record, the one just before the modif. We need both : the previous and the new one.
=back
sub ModZebra {
###Accepts a $server variable thus we can use it for biblios authorities or other zebra dbs
- my ( $biblionumber, $op, $server, $newRecord ) = @_;
+ my ( $biblionumber, $op, $server, $oldRecord, $newRecord ) = @_;
my $dbh=C4::Context->dbh;
# true ModZebra commented until indexdata fixes zebraDB crashes (it seems they occur on multiple updates
# lock the nozebra table : we will read index lines, update them in Perl process
# and write everything in 1 transaction.
# lock the table to avoid someone else overwriting what we are doing
- $dbh->do('LOCK TABLES nozebra WRITE,biblio WRITE,biblioitems WRITE, systempreferences WRITE, auth_types WRITE, auth_header WRITE');
- my %result; # the result hash that will be builded by deletion / add, and written on mySQL at the end, to improve speed
- my $record;
- if ($server eq 'biblioserver') {
- $record= GetMarcBiblio($biblionumber);
- } else {
- $record= C4::AuthoritiesMarc::GetAuthority($biblionumber);
- }
+ $dbh->do('LOCK TABLES nozebra WRITE,biblio WRITE,biblioitems WRITE, systempreferences WRITE, auth_types WRITE, auth_header WRITE, auth_subfield_structure READ');
+ my %result; # the result hash that will be built by deletion / add, and written on mySQL at the end, to improve speed
if ($op eq 'specialUpdate') {
# OK, we have to add or update the record
# 1st delete (virtually, in indexes), if record actually exists
- if ($record) {
- %result = _DelBiblioNoZebra($biblionumber,$record,$server);
+ if ($oldRecord) {
+ %result = _DelBiblioNoZebra($biblionumber,$oldRecord,$server);
}
# ... add the record
%result=_AddBiblioNoZebra($biblionumber,$newRecord, $server, %result);
} else {
# it's a deletion, delete the record...
# warn "DELETE the record $biblionumber on $server".$record->as_formatted;
- %result=_DelBiblioNoZebra($biblionumber,$record,$server);
+ %result=_DelBiblioNoZebra($biblionumber,$oldRecord,$server);
}
# ok, now update the database...
my $sth = $dbh->prepare("UPDATE nozebra SET biblionumbers=? WHERE server=? AND indexname=? AND value=?");
}
}
$dbh->do('UNLOCK TABLES');
-
} else {
#
# we use zebra, just fill zebraqueue table
#
- my $sth=$dbh->prepare("INSERT INTO zebraqueue (biblio_auth_number,server,operation) VALUES(?,?,?)");
- $sth->execute($biblionumber,$server,$op);
- $sth->finish;
+ my $check_sql = "SELECT COUNT(*) FROM zebraqueue
+ WHERE server = ?
+ AND biblio_auth_number = ?
+ AND operation = ?
+ AND done = 0";
+ my $check_sth = $dbh->prepare_cached($check_sql);
+ $check_sth->execute($server, $biblionumber, $op);
+ my ($count) = $check_sth->fetchrow_array;
+ $check_sth->finish();
+ if ($count == 0) {
+ my $sth=$dbh->prepare("INSERT INTO zebraqueue (biblio_auth_number,server,operation) VALUES(?,?,?)");
+ $sth->execute($biblionumber,$server,$op);
+ $sth->finish;
+ }
}
}
$title = lc($record->subfield($titletag,$titlesubfield));
} else {
# for authorities, the "title" is the $a mainentry
- my $authref = C4::AuthoritiesMarc::GetAuthType($record->subfield(152,'b'));
+ my ($auth_type_tag, $auth_type_sf) = C4::AuthoritiesMarc::get_auth_type_location();
+ my $authref = C4::AuthoritiesMarc::GetAuthType($record->subfield($auth_type_tag, $auth_type_sf));
warn "ERROR : authtype undefined for ".$record->as_formatted unless $authref;
$title = $record->subfield($authref->{auth_tag_to_report},'a');
$index{'mainmainentry'}= $authref->{'auth_tag_to_report'}.'a';
$index{'mainentry'} = $authref->{'auth_tag_to_report'}.'*';
- $index{'auth_type'} = '152b';
+ $index{'auth_type'} = "${auth_type_tag}${auth_type_sf}";
}
my %result;
} else {
# warn "server : $server";
# for authorities, the "title" is the $a mainentry
- my $authref = C4::AuthoritiesMarc::GetAuthType($record->subfield(152,'b'));
+ my ($auth_type_tag, $auth_type_sf) = C4::AuthoritiesMarc::get_auth_type_location();
+ my $authref = C4::AuthoritiesMarc::GetAuthType($record->subfield($auth_type_tag, $auth_type_sf));
warn "ERROR : authtype undefined for ".$record->as_formatted unless $authref;
$title = $record->subfield($authref->{auth_tag_to_report},'a');
$index{'mainmainentry'} = $authref->{auth_tag_to_report}.'a';
$index{'mainentry'} = $authref->{auth_tag_to_report}.'*';
- $index{'auth_type'} = '152b';
+ $index{'auth_type'} = "${auth_type_tag}${auth_type_sf}";
}
# remove blancks comma (that could cause problem when decoding the string for CQL retrieval) and regexp specific values
- $title =~ s/ |,|;|\[|\]|\(|\)|\*|-|'|=//g;
+ $title =~ s/ |\.|,|;|\[|\]|\(|\)|\*|-|'|:|=|\r|\n//g;
# limit to 10 char, should be enough, and limit the DB size
$title = substr($title,0,10);
#parse each field
my $tag = $field->tag();
my $subfieldcode = $subfield->[0];
my $indexed=0;
+# warn "INDEXING :".$subfield->[1];
# check each index to see if the subfield is stored somewhere
# otherwise, store it in __RAW__ index
foreach my $key (keys %index) {
$indexed=1;
my $line= lc $subfield->[1];
# remove meaningless value in the field...
- $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
+ $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
# ... and split in words
foreach (split / /,$line) {
next unless $_; # skip empty values (multiple spaces)
# the subfield is not indexed, store it in __RAW__ index anyway
unless ($indexed) {
my $line= lc $subfield->[1];
- $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:/ /g;
+ $line =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|<|>|&|\+|\*|\/|=|:|\r|\n/ /g;
# ... and split in words
foreach (split / /,$line) {
next unless $_; # skip empty values (multiple spaces)
# drop old field and create new one...
$old_field = $record->field($biblio_tag);
- $record->delete_field($old_field);
+ $record->delete_field($old_field) if $old_field;
$record->append_fields($new_field);
# deal with biblioitemnumber
}
# drop old field and create new one...
$old_field = $record->field($biblioitem_tag);
- $record->delete_field($old_field);
+ $record->delete_field($old_field) if $old_field;
$record->insert_fields_ordered($new_field);
} else {
# drop old field and create new one...
my $old_field = $record->field($biblio_tag);
- $record->delete_field($old_field);
+ $record->delete_field($old_field) if $old_field;
$record->insert_fields_ordered($new_field);
}
}
+=head2 _koha_marc_update_biblioitem_cn_sort
+
+=over 4
+
+_koha_marc_update_biblioitem_cn_sort($marc, $biblioitem, $frameworkcode);
+
+=back
+
+Given a MARC bib record and the biblioitem hash, update the
+subfield that contains a copy of the value of biblioitems.cn_sort.
+
+=cut
+
+sub _koha_marc_update_biblioitem_cn_sort {
+ my $marc = shift;
+ my $biblioitem = shift;
+ my $frameworkcode= shift;
+
+ my ($biblioitem_tag, $biblioitem_subfield ) = GetMarcFromKohaField("biblioitems.cn_sort",$frameworkcode);
+ return unless $biblioitem_tag;
+
+ my ($cn_sort) = GetClassSort($biblioitem->{'biblioitems.cn_source'}, $biblioitem->{'cn_class'}, $biblioitem->{'cn_item'} );
+
+ if (my $field = $marc->field($biblioitem_tag)) {
+ $field->delete_subfield(code => $biblioitem_subfield);
+ if ($cn_sort ne '') {
+ $field->add_subfields($biblioitem_subfield => $cn_sort);
+ }
+ } else {
+ # if we get here, no biblioitem tag is present in the MARC record, so
+ # we'll create it if $cn_sort is not empty -- this would be
+ # an odd combination of events, however
+ if ($cn_sort) {
+ $marc->insert_grouped_field(MARC::Field->new($biblioitem_tag, ' ', ' ', $biblioitem_subfield => $cn_sort));
+ }
+ }
+}
+
=head2 _koha_add_biblio
=over 4
MARC::Field->new( 100, "", "", "a" => $string ) );
}
}
- ModZebra($biblionumber,"specialUpdate","biblioserver",$record);
+ my $oldRecord;
+ if (C4::Context->preference("NoZebra")) {
+ # only NoZebra indexing needs to have
+ # the previous version of the record
+ $oldRecord = GetMarcBiblio($biblionumber);
+ }
$sth =
$dbh->prepare(
"UPDATE biblioitems SET marc=?,marcxml=? WHERE biblionumber=?");
$sth->execute( $record->as_usmarc(), $record->as_xml_record($encoding),
$biblionumber );
$sth->finish;
+ ModZebra($biblionumber,"specialUpdate","biblioserver",$oldRecord,$record);
return $biblionumber;
}
return $serviceOptions;
}
+=head3 get_biblio_authorised_values
+
+ find the types and values for all authorised values assigned to this biblio.
+
+ parameters:
+ biblionumber
+
+ returns: a hashref malling the authorised value to the value set for this biblionumber
+
+ $authorised_values = {
+ 'Scent' => 'flowery',
+ 'Audience' => 'Young Adult',
+ 'itemtypes' => 'SER',
+ };
+
+ Notes: forlibrarian should probably be passed in, and called something different.
+
+
+=cut
+
+sub get_biblio_authorised_values {
+ my $biblionumber = shift;
+
+ my $forlibrarian = 1; # are we in staff or opac?
+ my $frameworkcode = GetFrameworkCode( $biblionumber );
+
+ my $authorised_values;
+
+ my $record = GetMarcBiblio( $biblionumber )
+ or return $authorised_values;
+ my $tagslib = GetMarcStructure( $forlibrarian, $frameworkcode )
+ or return $authorised_values;
+
+ # assume that these entries in the authorised_value table are bibliolevel.
+ # ones that start with 'item%' are item level.
+ my $query = q(SELECT distinct authorised_value, kohafield
+ FROM marc_subfield_structure
+ WHERE authorised_value !=''
+ AND (kohafield like 'biblio%'
+ OR kohafield like '') );
+ my $bibliolevel_authorised_values = C4::Context->dbh->selectall_hashref( $query, 'authorised_value' );
+
+ foreach my $tag ( keys( %$tagslib ) ) {
+ foreach my $subfield ( keys( %{$tagslib->{ $tag }} ) ) {
+ # warn "checking $subfield. type is: " . ref $tagslib->{ $tag }{ $subfield };
+ if ( 'HASH' eq ref $tagslib->{ $tag }{ $subfield } ) {
+ if ( exists $tagslib->{ $tag }{ $subfield }{'authorised_value'} && exists $bibliolevel_authorised_values->{ $tagslib->{ $tag }{ $subfield }{'authorised_value'} } ) {
+ if ( defined $record->field( $tag ) ) {
+ my $this_subfield_value = $record->field( $tag )->subfield( $subfield );
+ if ( defined $this_subfield_value ) {
+ $authorised_values->{ $tagslib->{ $tag }{ $subfield }{'authorised_value'} } = $this_subfield_value;
+ }
+ }
+ }
+ }
+ }
+ }
+ # warn ( Data::Dumper->Dump( [ $authorised_values ], [ 'authorised_values' ] ) );
+ return $authorised_values;
+}
+
+
1;
__END__