Merge branch 'new/enh/bug_5579' into kcmaster
authorChris Cormack <chrisc@catalyst.net.nz>
Wed, 20 Apr 2011 23:48:11 +0000 (11:48 +1200)
committerChris Cormack <chrisc@catalyst.net.nz>
Wed, 20 Apr 2011 23:48:11 +0000 (11:48 +1200)
Conflicts:
C4/Biblio.pm

16 files changed:
C4/Biblio.pm
C4/Charset.pm
C4/Items.pm
C4/Record.pm
basket/downloadcart.pl
catalogue/export.pl
cataloguing/additem.pl
misc/maintenance/remove_items_from_biblioitems.pl [new file with mode: 0755]
misc/maintenance/sync_items_in_marc_bib.pl [deleted file]
misc/migration_tools/bulkmarcimport.pl
misc/migration_tools/rebuild_zebra.pl
opac/opac-downloadcart.pl
opac/opac-downloadshelf.pl
opac/opac-export.pl
tools/export.pl
virtualshelves/downloadshelf.pl

index 120592f..c9590c2 100755 (executable)
@@ -2,6 +2,7 @@ package C4::Biblio;
 
 # Copyright 2000-2002 Katipo Communications
 # Copyright 2010 BibLibre
+# Copyright 2011 Equinox Software, Inc.
 #
 # This file is part of Koha.
 #
@@ -35,6 +36,7 @@ use C4::ClassSource;
 use C4::Charset;
 require C4::Heading;
 require C4::Serials;
+require C4::Items;
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -302,39 +304,7 @@ sub ModBiblio {
 
     $frameworkcode = "" unless $frameworkcode;
 
-    # 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
-    # and the biblio will be re-encoded.
-    # strange, I (Paul P.) searched more than 1 day to understand what happends
-    # but could only solve the problem this way...
-    my @fields = $oldRecord->field($itemtag);
-    foreach my $fielditem (@fields) {
-        my $field;
-        foreach ( $fielditem->subfields() ) {
-            # re-encode the subfield only if it isn't already in utf-8.
-            my ($tag, $value) = @$_;
-            $tag = Encode::encode('utf-8', $tag) unless utf8::is_utf8($tag);
-            $value = Encode::encode('utf-8', $value) unless utf8::is_utf8($value);
-
-            if ($field) {
-                $field->add_subfields( $tag => $value );
-            } else {
-                $field = MARC::Field->new( "$itemtag", '', '', $tag => $value );
-            }
-        }
-        $record->append_fields($field);
-    }
+    _strip_item_fields($record, $frameworkcode);
 
     foreach my $field ($record->fields()) {
         if (! $field->is_control_field()) {
@@ -368,6 +338,29 @@ sub ModBiblio {
     return 1;
 }
 
+=head2 _strip_item_fields
+
+  _strip_item_fields($record, $frameworkcode)
+
+Utility routine to remove item tags from a
+MARC bib.
+
+=cut
+
+sub _strip_item_fields {
+    my $record = shift;
+    my $frameworkcode = shift;
+    # 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 );
+
+    # 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);
+    }
+}
+
 =head2 ModBiblioframework
 
    ModBiblioframework($biblionumber,$frameworkcode);
@@ -760,7 +753,7 @@ Return the ISBD view which can be included in opac and intranet
 
 sub GetISBDView {
     my ( $biblionumber, $template ) = @_;
-    my $record   = GetMarcBiblio($biblionumber);
+    my $record   = GetMarcBiblio($biblionumber, 1);
     return undef unless defined $record;
     my $itemtype = &GetFrameworkCode($biblionumber);
     my ( $holdingbrtagf, $holdingbrtagsubf ) = &GetMarcFromKohaField( "items.holdingbranch", $itemtype );
@@ -1047,16 +1040,18 @@ sub GetMarcFromKohaField {
 
 =head2 GetMarcBiblio
 
-  my $record = GetMarcBiblio($biblionumber);
+  my $record = GetMarcBiblio($biblionumber, [$embeditems]);
 
 Returns MARC::Record representing bib identified by
 C<$biblionumber>.  If no bib exists, returns undef.
-The MARC record contains both biblio & item data.
+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.
 
 =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=? ");
     $sth->execute($biblionumber);
@@ -1068,6 +1063,9 @@ sub GetMarcBiblio {
     if ($marcxml) {
         $record = eval { MARC::Record::new_from_xml( $marcxml, "utf8", C4::Context->preference('marcflavour') ) };
         if ($@) { warn " problem with :$biblionumber : $@ \n$marcxml"; }
+        return unless $record;
+
+       C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) if ($embeditems);
 
         #      $record = MARC::Record::new_from_usmarc( $marc) if $marc;
         return $record;
@@ -2655,6 +2653,35 @@ sub GetNoZebraIndexes {
     return %indexes;
 }
 
+=head2 EmbedItemsInMarcBiblio
+
+    EmbedItemsInMarcBiblio($marc, $biblionumber);
+
+Given a MARC::Record object containing a bib record,
+modify it to include the items attached to it as 9XX
+per the bib's MARC framework.
+
+=cut
+
+sub EmbedItemsInMarcBiblio {
+    my ($marc, $biblionumber) = @_;
+
+    my $frameworkcode = GetFrameworkCode($biblionumber);
+    _strip_item_fields($marc, $frameworkcode);
+
+    # ... and embed the current items
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber = ?");
+    $sth->execute($biblionumber);
+    my @item_fields;
+    my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField( "items.itemnumber", $frameworkcode );
+    while (my ($itemnumber) = $sth->fetchrow_array) {
+        my $item_marc = C4::Items::GetMarcItem($biblionumber, $itemnumber);
+        push @item_fields, $item_marc->field($itemtag);
+    }
+    $marc->insert_fields_ordered(@item_fields);
+}
+
 =head1 INTERNAL FUNCTIONS
 
 =head2 _DelBiblioNoZebra($biblionumber,$record,$server);
index a4a06e7..a4e6b71 100644 (file)
@@ -112,7 +112,7 @@ sub IsStringUTF8ish {
 
 =head2 SetUTF8Flag
 
-  my $marc_record = SetUTF8Flag($marc_record);
+  my $marc_record = SetUTF8Flag($marc_record, $nfd);
 
 This function sets the PERL UTF8 flag for data.
 It is required when using new_from_usmarc 
@@ -120,6 +120,8 @@ since MARC::File::USMARC does not handle PERL UTF8 setting.
 When editing unicode marc records fields and subfields, you
 would end up in double encoding without using this function. 
 
+If $nfd is set, string normalization will use NFD instead of NFC
+
 FIXME
 In my opinion, this function belongs to MARC::Record and not
 to this package.
@@ -128,13 +130,13 @@ But since it handles charset, and MARC::Record, it finds its way in that package
 =cut
 
 sub SetUTF8Flag{
-       my ($record)=@_;
+       my ($record, $nfd)=@_;
        return unless ($record && $record->fields());
        foreach my $field ($record->fields()){
                if ($field->tag()>=10){
                        my @subfields;
                        foreach my $subfield ($field->subfields()){
-                               push @subfields,($$subfield[0],NormalizeString($$subfield[1]));
+                               push @subfields,($$subfield[0],NormalizeString($$subfield[1],$nfd));
                        }
                        my $newfield=MARC::Field->new(
                                                        $field->tag(),
index 01509c2..44272e2 100644 (file)
@@ -34,6 +34,8 @@ require C4::Reserves;
 use C4::Charset;
 use C4::Acquisition;
 use List::MoreUtils qw/any/;
+use Data::Dumper; # used as part of logging item record changes, not just for
+                  # debugging; so please don't remove this
 
 use vars qw($VERSION @ISA @EXPORT);
 
@@ -262,9 +264,7 @@ sub AddItem {
        my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} );
     $item->{'itemnumber'} = $itemnumber;
 
-    # create MARC tag representing item and add to bib
-    my $new_item_marc = _marc_from_item_hash($item, $frameworkcode, $unlinked_item_subfields);
-    _add_item_field_to_biblio($new_item_marc, $item->{'biblionumber'}, $frameworkcode );
+    ModZebra( $item->{biblionumber}, "specialUpdate", "biblioserver", undef, undef );
    
     logaction("CATALOGUING", "ADD", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
     
@@ -370,7 +370,7 @@ sub AddItemBatchFromMarc {
     }
 
     # update the MARC biblio
-    $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
#   $biblionumber = ModBiblioMarc( $record, $biblionumber, $frameworkcode );
 
     return (\@itemnumbers, \@errors);
 }
@@ -506,18 +506,11 @@ sub ModItem {
     # update items table
     _koha_modify_item($item);
 
-    # update biblio MARC XML
-    my $whole_item = GetItem($itemnumber) or die "FAILED GetItem($itemnumber)";
+    # request that bib be reindexed so that searching on current
+    # item status is possible
+    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
 
-    unless (defined $unlinked_item_subfields) {
-        $unlinked_item_subfields = _parse_unlinked_item_subfields_from_xml($whole_item->{'more_subfields_xml'});
-    }
-    my $new_item_marc = _marc_from_item_hash($whole_item, $frameworkcode, $unlinked_item_subfields) 
-        or die "FAILED _marc_from_item_hash($whole_item, $frameworkcode)";
-    
-    _replace_item_field_in_biblio($new_item_marc, $biblionumber, $itemnumber, $frameworkcode);
-       ($new_item_marc       eq '0') and die "$new_item_marc is '0', not hashref";  # logaction line would crash anyway
-    logaction("CATALOGUING", "MODIFY", $itemnumber, $new_item_marc->as_formatted) if C4::Context->preference("CataloguingLog");
+    logaction("CATALOGUING", "MODIFY", $itemnumber, Dumper($item)) if C4::Context->preference("CataloguingLog");
 }
 
 =head2 ModItemTransfer
@@ -578,23 +571,13 @@ sub DelItem {
 
     # get the MARC record
     my $record = GetMarcBiblio($biblionumber);
-    my $frameworkcode = GetFrameworkCode($biblionumber);
+    ModZebra( $biblionumber, "specialUpdate", "biblioserver", undef, undef );
 
     # backup the record
     my $copy2deleted = $dbh->prepare("UPDATE deleteditems SET marc=? WHERE itemnumber=?");
     $copy2deleted->execute( $record->as_usmarc(), $itemnumber );
 
     #search item field code
-    my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
-    my @fields = $record->field($itemtag);
-
-    # delete the item specified
-    foreach my $field (@fields) {
-        if ( $field->subfield($itemsubfield) eq $itemnumber ) {
-            $record->delete_field($field);
-        }
-    }
-    &ModBiblioMarc( $record, $biblionumber, $frameworkcode );
     logaction("CATALOGUING", "DELETE", $itemnumber, "item") if C4::Context->preference("CataloguingLog");
 }
 
@@ -2083,59 +2066,18 @@ sub MoveItemFromBiblio {
     $sth = $dbh->prepare("UPDATE items SET biblioitemnumber = ?, biblionumber = ? WHERE itemnumber = ? AND biblionumber = ?");
     my $return = $sth->execute($tobiblioitem, $tobiblio, $itemnumber, $frombiblio);
     if ($return == 1) {
-
-       # Getting framework
-       my $frameworkcode = GetFrameworkCode($frombiblio);
-
-       # Getting marc field for itemnumber
-       my ($itemtag, $itemsubfield) = GetMarcFromKohaField('items.itemnumber', $frameworkcode);
-
-       # Getting the record we want to move the item from
-       my $record = GetMarcBiblio($frombiblio);
-
-       # The item we want to move
-       my $item;
-
-       # For each item
-       foreach my $fielditem ($record->field($itemtag)){
-               # If it is the item we want to move
-               if ($fielditem->subfield($itemsubfield) == $itemnumber) {
-                   # We save it
-                   $item = $fielditem;
-                   # Then delete it from the record
-                   $record->delete_field($fielditem) 
-               }
-       }
-
-       # If we found an item (should always true, except in case of database-marcxml inconsistency)
-       if ($item) {
-
+        ModZebra( $tobiblio, "specialUpdate", "biblioserver", undef, undef );
+        ModZebra( $frombiblio, "specialUpdate", "biblioserver", undef, undef );
            # Checking if the item we want to move is in an order 
-           my $order = GetOrderFromItemnumber($itemnumber);
+        my $order = GetOrderFromItemnumber($itemnumber);
            if ($order) {
-               # Replacing the biblionumber within the order if necessary
-               $order->{'biblionumber'} = $tobiblio;
+                   # Replacing the biblionumber within the order if necessary
+                   $order->{'biblionumber'} = $tobiblio;
                ModOrder($order);
            }
-
-           # Saving the modification
-           ModBiblioMarc($record, $frombiblio, $frameworkcode);
-
-           # Getting the record we want to move the item to
-           $record = GetMarcBiblio($tobiblio);
-
-           # Inserting the previously saved item
-           $record->insert_fields_ordered($item);      
-
-           # Saving the modification
-           ModBiblioMarc($record, $tobiblio, $frameworkcode);
-
-       } else {
-           return undef;
+        return $tobiblio;
        }
-    } else {
-       return undef;
-    }
+    return;
 }
 
 =head2 DelItemCheck
@@ -2296,68 +2238,6 @@ sub _marc_from_item_hash {
     return $item_marc;
 }
 
-=head2 _add_item_field_to_biblio
-
-  _add_item_field_to_biblio($item_marc, $biblionumber, $frameworkcode);
-
-Adds the fields from a MARC record containing the
-representation of a Koha item record to the MARC
-biblio record.  The input C<$item_marc> record
-is expect to contain just one field, the embedded
-item information field.
-
-=cut
-
-sub _add_item_field_to_biblio {
-    my ($item_marc, $biblionumber, $frameworkcode) = @_;
-
-    my $biblio_marc = GetMarcBiblio($biblionumber);
-    foreach my $field ($item_marc->fields()) {
-        $biblio_marc->append_fields($field);
-    }
-
-    ModBiblioMarc($biblio_marc, $biblionumber, $frameworkcode);
-}
-
-=head2 _replace_item_field_in_biblio
-
-  &_replace_item_field_in_biblio($item_marc, $biblionumber, $itemnumber, $frameworkcode)
-
-Given a MARC::Record C<$item_marc> containing one tag with the MARC 
-representation of the item, examine the biblio MARC
-for the corresponding tag for that item and 
-replace it with the tag from C<$item_marc>.
-
-=cut
-
-sub _replace_item_field_in_biblio {
-    my ($ItemRecord, $biblionumber, $itemnumber, $frameworkcode) = @_;
-    my $dbh = C4::Context->dbh;
-    
-    # get complete MARC record & replace the item field by the new one
-    my $completeRecord = GetMarcBiblio($biblionumber);
-    my ($itemtag,$itemsubfield) = GetMarcFromKohaField("items.itemnumber",$frameworkcode);
-    my $itemField = $ItemRecord->field($itemtag);
-    my @items = $completeRecord->field($itemtag);
-    my $found = 0;
-    foreach (@items) {
-        if ($_->subfield($itemsubfield) eq $itemnumber) {
-            $_->replace_with($itemField);
-            $found = 1;
-        }
-    }
-  
-    unless ($found) { 
-        # If we haven't found the matching field,
-        # just add it.  However, this means that
-        # there is likely a bug.
-        $completeRecord->append_fields($itemField);
-    }
-
-    # save the record
-    ModBiblioMarc($completeRecord, $biblionumber, $frameworkcode);
-}
-
 =head2 _repack_item_errors
 
 Add an error message hash generated by C<CheckItemPreSave>
index 990bb50..c5727f3 100644 (file)
@@ -359,7 +359,7 @@ sub marcrecord2csv {
     my $output;
 
     # Getting the record
-    my $record = GetMarcBiblio($biblio);
+    my $record = GetMarcBiblio($biblio, 1);
     next unless $record;
     # Getting the framework
     my $frameworkcode = GetFrameworkCode($biblio);
index 456f0a4..392a3e4 100755 (executable)
@@ -65,7 +65,7 @@ if ($bib_list && $format) {
 
         foreach my $biblio (@bibs) {
 
-            my $record = GetMarcBiblio($biblio);
+            my $record = GetMarcBiblio($biblio, 1);
 
             if ($format eq 'iso2709') {
                 $output .= $record->as_usmarc();
index f6f02d7..9bd49de 100755 (executable)
@@ -15,14 +15,9 @@ my $op=$query->param("op");
 my $format=$query->param("format");
 if ($op eq "export") {
        my $biblionumber = $query->param("bib");
-       my $dbh=C4::Context->dbh;
-       my $sth;
-       if ($biblionumber) {
-               $sth=$dbh->prepare("SELECT marc FROM biblioitems WHERE biblionumber =?");
-               $sth->execute($biblionumber);
-       }
-       while (my ($marc) = $sth->fetchrow) {
-               if ($marc){
+               if ($biblionumber){
+
+                       my $marc = GetMarcBiblio($biblionumber, 1);
 
                        if ($format =~ /endnote/) {
                                $marc = marc2endnote($marc);
@@ -44,12 +39,12 @@ if ($op eq "export") {
                                $marc = $marc->as_usmarc();
                        }
                        elsif ($format =~ /utf8/) {
-                               #default
+                               C4::Charset::SetUTF8Flag($marc, 1);
+                               $marc = $marc->as_usmarc();
                        }
                        print $query->header(
                                -type => 'application/octet-stream',
                 -attachment=>"bib-$biblionumber.$format");
                        print $marc;
                }
-       }
 }
index e2dfc02..43fb19f 100755 (executable)
@@ -494,13 +494,14 @@ if ($op eq "additem") {
 
 # now, build existiing item list
 my $temp = GetMarcBiblio( $biblionumber );
-my @fields = $temp->fields();
 #my @fields = $record->fields();
 my %witness; #---- stores the list of subfields used at least once, with the "meaning" of the code
 my @big_array;
 #---- finds where items.itemnumber is stored
 my (  $itemtagfield,   $itemtagsubfield) = &GetMarcFromKohaField("items.itemnumber", $frameworkcode);
 my ($branchtagfield, $branchtagsubfield) = &GetMarcFromKohaField("items.homebranch", $frameworkcode);
+C4::Biblio::EmbedItemsInMarcBiblio($temp, $biblionumber);
+my @fields = $temp->fields();
 
 foreach my $field (@fields) {
     next if ( $field->tag() < 10 );
diff --git a/misc/maintenance/remove_items_from_biblioitems.pl b/misc/maintenance/remove_items_from_biblioitems.pl
new file mode 100755 (executable)
index 0000000..0778b29
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+
+# Copyright 2010 BibLibre
+# Copyright 2011 Equinox Software, Inc.
+#
+# 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 2 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+
+use C4::Context;
+use C4::Biblio;
+use Getopt::Long;
+
+my ($wherestring, $run, $want_help);
+my $result = GetOptions(
+    'where:s'      => \$wherestring,
+    '--run'        => \$run,
+    'help|h'       => \$want_help,
+);
+
+if ( not $result or not $run or $want_help ) {
+    print_usage();
+    exit 0;
+}
+
+my $dbh = C4::Context->dbh;
+my $querysth =  qq{SELECT biblionumber from biblioitems };
+$querysth    .= " WHERE $wherestring " if ($wherestring);
+my $query = $dbh->prepare($querysth);
+$query->execute;
+while (my $biblionumber = $query->fetchrow){
+    my $record = GetMarcBiblio($biblionumber);
+    
+    if ($record) {
+        ModBiblio($record, $biblionumber, GetFrameworkCode($biblionumber)) ;
+    }
+    else {
+        print "error in $biblionumber : can't parse biblio";
+    }
+}
+
+sub print_usage {
+    print <<_USAGE_;
+$0: removes items from selected biblios
+
+This utility is meant to be run as part of the upgrade to
+Koha 3.4.  It removes the 9XX fields in the bib records that
+store a (now) duplicate copy of the item record information.  After
+running this utility, a full reindexing of the bibliographic records
+should be run using rebuild_zebra.pl -b -r.
+
+Parameters:
+    -where                  use this to limit modifications to selected biblios
+    --run                   perform the update
+    --help or -h            show this message
+_USAGE_
+}
diff --git a/misc/maintenance/sync_items_in_marc_bib.pl b/misc/maintenance/sync_items_in_marc_bib.pl
deleted file mode 100755 (executable)
index d3eb2ef..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-#use warnings; FIXME - Bug 2505
-BEGIN {
-    # find Koha's Perl modules
-    # test carefully before changing this
-    use FindBin;
-    eval { require "$FindBin::Bin/../kohalib.pl" };
-}
-
-use C4::Context;
-use C4::Biblio;
-use C4::Items;
-use Getopt::Long;
-
-$| = 1;
-
-# command-line parameters
-my $want_help = 0;
-my $do_update = 0;
-my $wherestrings;
-
-my $result = GetOptions(
-    'run-update'    => \$do_update,
-    'where=s@'         => \$wherestrings,
-    'h|help'        => \$want_help,
-);
-
-if (not $result or $want_help or not $do_update) {
-    print_usage();
-    exit 0;
-}
-
-my $num_bibs_processed     = 0;
-my $num_bibs_modified      = 0;
-my $num_marc_items_deleted = 0;
-my $num_marc_items_added   = 0;
-my $num_bad_bibs           = 0;
-my $dbh = C4::Context->dbh;
-$dbh->{AutoCommit} = 0;
-
-our ($itemtag, $itemsubfield) = GetMarcFromKohaField("items.itemnumber", '');
-our ($item_sth) = $dbh->prepare("SELECT itemnumber FROM items WHERE biblionumber = ?");
-
-process_bibs();
-$dbh->commit();
-
-exit 0;
-
-sub process_bibs {
-    my $sql = "SELECT biblionumber FROM biblio JOIN biblioitems USING (biblionumber)";
-    $sql.="WHERE ". join(" AND ",@$wherestrings) if ($wherestrings);
-    $sql.="ORDER BY biblionumber ASC";
-    my $sth = $dbh->prepare($sql);
-    eval{$sth->execute();};
-    if ($@){ die "error $@";};
-    while (my ($biblionumber) = $sth->fetchrow_array()) {
-        $num_bibs_processed++;
-        process_bib($biblionumber);
-
-        if (($num_bibs_processed % 100) == 0) {
-            print_progress_and_commit($num_bibs_processed);
-        }
-    }
-
-    $dbh->commit;
-
-    print <<_SUMMARY_;
-
-Embedded item synchronization report
-------------------------------------
-Number of bibs checked:                   $num_bibs_processed
-Number of bibs modified:                  $num_bibs_modified
-Number of item fields removed from bibs:  $num_marc_items_deleted
-Number of item fields added to bibs:      $num_marc_items_added
-Number of bibs with errors:               $num_bad_bibs
-_SUMMARY_
-}
-
-sub process_bib {
-    my $biblionumber = shift;
-
-    my $bib = GetMarcBiblio($biblionumber);
-    unless (defined $bib) {
-        print "\nCould not retrieve bib $biblionumber from the database - record is corrupt.\n";
-        $num_bad_bibs++;
-        return;
-    }
-
-    my $bib_modified = 0;
-
-    # delete any item tags
-    foreach my $field ($bib->field($itemtag)) {
-        unless ($bib->delete_field($field)) {
-            warn "Could not delete item in $itemtag for biblionumber $biblionumber";
-            next;
-        }
-        $num_marc_items_deleted++;
-        $bib_modified = 1;
-    }
-
-    # add back items from items table
-    $item_sth->execute($biblionumber);
-    while (my $itemnumber = $item_sth->fetchrow_array) {
-        my $marc_item = C4::Items::GetMarcItem($biblionumber, $itemnumber);
-        unless ($marc_item) {
-            warn "FAILED C4::Items::GetMarcItem for biblionumber=$biblionumber, itemnumber=$itemnumber";
-            next;
-        }
-        foreach my $item_field ($marc_item->field($itemtag)) {
-            $bib->insert_fields_ordered($item_field);
-            $num_marc_items_added++;
-            $bib_modified = 1;
-        }
-    }
-
-    if ($bib_modified) {
-        ModBiblioMarc($bib, $biblionumber, GetFrameworkCode($biblionumber));
-        $num_bibs_modified++;
-    }
-
-}
-
-sub print_progress_and_commit {
-    my $recs = shift;
-    $dbh->commit();
-    print "... processed $recs records\n";
-}
-
-sub print_usage {
-    print <<_USAGE_;
-$0: synchronize item data embedded in MARC bibs
-
-Replaces the item data embedded in the MARC bib 
-records (for indexing) with the authoritative 
-item data as stored in the items table.
-
-If Zebra is used, run rebuild_zebra.pl -b -r after
-running this script.
-
-NOTE: this script should be run only if there is
-reason to suspect that the embedded item tags are
-not in sync with the items table.
-
-Parameters:
-    --run-update            run the synchronization
-    --where condition       selects the biblios on a criterium (Repeatable)
-    --help or -h            show this message.
-_USAGE_
-}
index ddfa5e0..4f738e8 100755 (executable)
@@ -323,10 +323,13 @@ RECORD: while (  ) {
                                printlog({id=>$id||$originalid||$biblionumber, op=>"insertitem",status=>"ERROR"}) if ($logfile);
                 # if we failed because of an exception, assume that 
                 # the MARC columns in biblioitems were not set.
+                C4::Biblio::_strip_item_fields($record, '');
                 ModBiblioMarc( $record, $biblionumber, '' );
                 next RECORD;
             } 
                        else{
+                C4::Biblio::_strip_item_fields($record, '');
+                ModBiblioMarc( $record, $biblionumber, '' ); # need to call because of defer_marc_save
                                printlog({id=>$id||$originalid||$biblionumber, op=>"insert",status=>"ok"}) if ($logfile);
                        }
             if ($#{ $errors_ref } > -1) { 
index 682c280..5be01cf 100755 (executable)
@@ -9,6 +9,7 @@ use File::Temp qw/ tempdir /;
 use File::Path;
 use C4::Biblio;
 use C4::AuthoritiesMarc;
+use C4::Items;
 
 # 
 # script that checks zebradir structure & create directories & mandatory files if needed
@@ -310,6 +311,7 @@ sub export_marc_records_from_sth {
     my $num_exported = 0;
     open (OUT, ">:utf8 ", "$directory/exported_records") or die $!;
     my $i = 0;
+    my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",'');
     while (my ($record_number) = $sth->fetchrow_array) {
         print "." if ( $verbose_logging );
         print "\r$i" unless ($i++ %100 or !$verbose_logging);
@@ -317,6 +319,25 @@ sub export_marc_records_from_sth {
             my $marcxml = $record_type eq 'biblio'
                           ? GetXmlBiblio( $record_number )
                           : GetAuthorityXML( $record_number );
+            if ($record_type eq 'biblio'){
+                my @items = GetItemsInfo($record_number, 'intra');
+                if (@items){
+                    my $record = MARC::Record->new;
+                    my @itemsrecord;
+                    foreach my $item (@items){
+                        my $record = Item2Marc($item, $record_number);                        
+                        push @itemsrecord, $record->field($itemtag);
+                    }
+                    $record->insert_fields_ordered(@itemsrecord);
+                    my $itemsxml=$record->as_xml_record();
+                    my $searchstring = '<record>\n';
+                    my $index = index($itemsxml, '<record>\n', 0);
+                    $itemsxml = substr($itemsxml, $index + length($searchstring));
+                    $searchstring = '</record>';
+                    $marcxml = substr($marcxml, 0, index($marcxml, $searchstring));
+                    $marcxml .= $itemsxml;
+                }
+            }
             if ( $marcxml ) {
                 print OUT $marcxml if $marcxml;
                 $num_exported++;
@@ -330,7 +351,7 @@ sub export_marc_records_from_sth {
             # strung together with no single root element.  zebraidx doesn't seem
             # to care, though, at least if you're using the GRS-1 filter.  It does
             # care if you're using the DOM filter, which requires valid XML file(s).
-            print OUT ($as_xml) ? $marc->as_xml_record() : $marc->as_usmarc();
+            print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc();
             $num_exported++;
         }
     }
@@ -358,7 +379,7 @@ sub export_marc_records_from_list {
             # strung together with no single root element.  zebraidx doesn't seem
             # to care, though, at least if you're using the GRS-1 filter.  It does
             # care if you're using the DOM filter, which requires valid XML file(s).
-            print OUT ($as_xml) ? $marc->as_xml_record() : $marc->as_usmarc();
+            print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference('marcflavour')) : $marc->as_usmarc();
             $num_exported++;
         }
     }
@@ -387,7 +408,7 @@ sub generate_deleted_marc_records {
             fix_unimarc_100($marc);
         }
 
-        print OUT ($as_xml) ? $marc->as_xml_record() : $marc->as_usmarc();
+        print OUT ($as_xml) ? $marc->as_xml_record(C4::Context->preference("marcflavour")) : $marc->as_usmarc();
         $num_exported++;
     }
     print "\nRecords exported: $num_exported\n" if ( $verbose_logging );
@@ -444,6 +465,8 @@ sub get_raw_marc_record {
                 return;
             }
         }
+        # ITEM
+        C4::Biblio::EmbedItemsInMarcBiblio($marc, $record_number);
     } else {
         eval { $marc = GetAuthority($record_number); };
         if ($@) {
index 7f2bb32..3a4cdc1 100755 (executable)
@@ -64,7 +64,7 @@ if ($bib_list && $format) {
     } else {
         foreach my $biblio (@bibs) {
 
-            my $record = GetMarcBiblio($biblio);
+            my $record = GetMarcBiblio($biblio, 1);
             next unless $record;
 
             if ($format eq 'iso2709') {
index ab1fe8d..ee9b0b1 100755 (executable)
@@ -68,7 +68,7 @@ if ($shelfid && $format) {
         foreach my $biblio (@$items) {
             my $biblionumber = $biblio->{biblionumber};
 
-            my $record = GetMarcBiblio($biblionumber);
+            my $record = GetMarcBiblio($biblionumber, 1);
             next unless $record;
 
             if ($format eq 'iso2709') {
index f9d3c25..e8f7ede 100755 (executable)
@@ -35,15 +35,11 @@ my $op=$query->param("op");
 my $format=$query->param("format");
 if ($op eq "export") {
        my $biblionumber = $query->param("bib");
-       my $dbh=C4::Context->dbh;
-       my $sth;
-       if ($biblionumber) {
-               $sth=$dbh->prepare("SELECT marc FROM biblioitems WHERE biblionumber =?");
-               $sth->execute($biblionumber);
-       }
-    my $error;
-       while (my ($marc) = $sth->fetchrow) {
-               if ($marc){
+       my $error;
+
+               if ($biblionumber){
+
+                       my $marc = GetMarcBiblio($biblionumber, 1);
 
                        if ($format =~ /endnote/) {
                                $marc = marc2endnote($marc);
@@ -60,32 +56,34 @@ if ($op eq "export") {
                        }
                        elsif ($format =~ /bibtex/) {
                                $marc = marc2bibtex(C4::Biblio::GetMarcBiblio($biblionumber),$biblionumber);
-                       }elsif ($format =~ /dc/) {
-                ($error,$marc) = marc2dcxml($marc,1);
+                       }
+                       elsif ($format =~ /dc/) {
+                               ($error,$marc) = marc2dcxml($marc,1);
                                $format = "dublin-core.xml";
                        }
                        elsif ($format =~ /marc8/) {
                                ($error,$marc) = changeEncoding($marc,"MARC","MARC21","MARC-8");
-                if (! $error){
-                    $marc = $marc->as_usmarc();
-                }
+                               if (! $error){
+                                   $marc = $marc->as_usmarc();
+                               }
                        }
                        elsif ($format =~ /utf8/) {
-                               #default
+                               C4::Charset::SetUTF8Flag($marc,1);
+                               $marc = $marc->as_usmarc();
                        }
-            if ($error){
-                print $query->header();
-                print $query->start_html();
-                print "<h1>An error occured </h1>";
-                print $error;
-                print $query->end_html();
-            }
-            else {
-                print $query->header(
-                               -type => 'application/octet-stream',
-                -attachment=>"bib-$biblionumber.$format");
-                print $marc;
-            }
+
+               if ($error){
+                   print $query->header();
+                   print $query->start_html();
+                   print "<h1>An error occured </h1>";
+                   print $error;
+                   print $query->end_html();
+               }
+               else {
+                   print $query->header(
+                                   -type => 'application/octet-stream',
+                   -attachment=>"bib-$biblionumber.$format");
+                   print $marc;
                }
-       }
+           }
 }
index fc0c7be..d858f44 100755 (executable)
@@ -133,13 +133,14 @@ if ($op eq "export") {
             next;
         }
         next if not defined $record;
-        if ( $dont_export_items || $strip_nonlocal_items || $limit_ind_branch) {
+        C4::Biblio::EmbedItemsInMarcBiblio($record, $biblionumber) unless $dont_export_items;
+        if ($strip_nonlocal_items || $limit_ind_branch) {
             my ( $homebranchfield, $homebranchsubfield ) =
                 GetMarcFromKohaField( 'items.homebranch', '' );
                        for my $itemfield ($record->field($homebranchfield)){
                                # if stripping nonlocal items, use loggedinuser's branch if they didn't select one
                                $branch = C4::Context->userenv->{'branch'} unless $branch;
-                $record->delete_field($itemfield) if($dont_export_items || ($itemfield->subfield($homebranchsubfield) ne $branch) ) ;
+                $record->delete_field($itemfield) if($itemfield->subfield($homebranchsubfield) ne $branch) ;
             }
         }
         
index 253eec1..1611f1a 100755 (executable)
@@ -68,7 +68,7 @@ if ($shelfid && $format) {
     foreach my $biblio (@$items) {
         my $biblionumber = $biblio->{biblionumber};
 
-        my $record = GetMarcBiblio($biblionumber);
+        my $record = GetMarcBiblio($biblionumber, 1);
 
         if ($format eq 'iso2709') {
             $output .= $record->as_usmarc();