View | Details | Raw Unified | Return to bug 10500
Collapse All | Expand All

(-)a/C4/Biblio.pm (+131 lines)
Lines 29-34 use MARC::File::USMARC; Link Here
29
use MARC::File::XML;
29
use MARC::File::XML;
30
use POSIX qw(strftime);
30
use POSIX qw(strftime);
31
use Module::Load::Conditional qw(can_load);
31
use Module::Load::Conditional qw(can_load);
32
use Business::ISBN;
32
33
33
use C4::Koha;
34
use C4::Koha;
34
use C4::Dates qw/format_date/;
35
use C4::Dates qw/format_date/;
Lines 73-78 BEGIN { Link Here
73
      &GetMarcControlnumber
74
      &GetMarcControlnumber
74
      &GetMarcNotes
75
      &GetMarcNotes
75
      &GetMarcISBN
76
      &GetMarcISBN
77
      &GetVariationsOfISBNs
78
      &GetVariationsOfISBN
79
      &GetNormalizedISBNsFromMarc
80
      &NormalizeISBN
76
      &GetMarcISSN
81
      &GetMarcISSN
77
      &GetMarcSubjects
82
      &GetMarcSubjects
78
      &GetMarcBiblio
83
      &GetMarcBiblio
Lines 1663-1668 sub GetMarcISBN { Link Here
1663
}    # end GetMarcISBN
1668
}    # end GetMarcISBN
1664
1669
1665
1670
1671
=head2 GetNormalizedISBNsFromMarc
1672
1673
  my @isbns = GetNormalizedISBNsFromMarc( $record );
1674
1675
  Returns a list of normalized ISBNs from a given record
1676
  or, in a scalar context, returns a string of normalized
1677
  isbns separated by ' | '
1678
1679
=cut
1680
1681
sub GetNormalizedISBNsFromMarc {
1682
    my ($record) = @_;
1683
    my ( $marc_field, $marc_subfield ) =
1684
      GetMarcFromKohaField('biblioitems.isbn');
1685
1686
    my @isbns;
1687
    foreach my $subfield ( $record->field( $marc_field, $marc_subfield ) ) {
1688
        my $isbn = NormalizeISBN( { isbn => $subfield->as_string } );
1689
        push( @isbns, $isbn ) if ($isbn);
1690
    }
1691
1692
    # remove duplicate isbns
1693
    @isbns = keys %{ { map { $_ => 1 } @isbns } };
1694
1695
    return wantarray ? @isbns : join( " | ", @isbns );
1696
}
1697
1698
1699
=head2 GetVariationsOfISBN
1700
1701
  my @isbns = GetVariationsOfISBN( $isbn );
1702
1703
  Returns a list of varations of the given isbn in
1704
  both ISBN-10 and ISBN-13 formats, with and without
1705
  hyphens.
1706
1707
  In a scalar context, the isbns are returned as a 
1708
  string delimited by ' | '.
1709
1710
=cut
1711
1712
sub GetVariationsOfISBN {
1713
    my ($isbn) = @_;
1714
1715
    my @isbns;
1716
1717
    push( @isbns, NormalizeISBN({ isbn => $isbn }) );
1718
    push( @isbns, NormalizeISBN({ isbn => $isbn, format => 'ISBN-10' }) );
1719
    push( @isbns, NormalizeISBN({ isbn => $isbn, format => 'ISBN-13' }) );
1720
    push( @isbns, NormalizeISBN({ isbn => $isbn, format => 'ISBN-10', strip_hyphens => 1 }) );
1721
    push( @isbns, NormalizeISBN({ isbn => $isbn, format => 'ISBN-13', strip_hyphens => 1 }) );
1722
1723
    return wantarray ? @isbns : join( " | ", @isbns );
1724
}
1725
1726
=head2 GetVariationsOfISBNs
1727
1728
  my @isbns = GetVariationsOfISBNs( @isbns );
1729
1730
  Returns a list of varations of the given isbns in
1731
  both ISBN-10 and ISBN-13 formats, with and without
1732
  hyphens.
1733
1734
  In a scalar context, the isbns are returned as a 
1735
  string delimited by ' | '.
1736
1737
=cut
1738
1739
sub GetVariationsOfISBNs {
1740
    my (@isbns) = @_;
1741
1742
    @isbns = map { GetVariationsOfISBN( $_ ) } @isbns;
1743
1744
    # remove duplicate isbns
1745
    @isbns = keys %{ { map { $_ => 1 } @isbns } };
1746
1747
    return wantarray ? @isbns : join( " | ", @isbns );
1748
}
1749
1750
=head2 NormalizedISBN
1751
1752
  my $isbns = NormalizedISBN({
1753
    isbn => $isbn,
1754
    strip_hyphens => [0,1],
1755
    format => ['ISBN-10', 'ISBN-13']
1756
  });
1757
1758
  Returns an isbn validated by Business::ISBN.
1759
  Optionally strips hyphens and/or forces the isbn
1760
  to be of the specified format.
1761
1762
  If the string cannot be validated as an isbn,
1763
  it returns nothing.
1764
1765
=cut
1766
1767
sub NormalizeISBN {
1768
    my ($params) = @_;
1769
1770
    my $string        = $params->{isbn};
1771
    my $strip_hyphens = $params->{strip_hyphens};
1772
    my $format        = $params->{format};
1773
1774
    my $isbn = Business::ISBN->new($string);
1775
1776
    if ( $isbn && $isbn->error != Business::ISBN::BAD_ISBN ) {
1777
1778
        if ( $format eq 'ISBN-10' ) {
1779
            $isbn = $isbn->as_isbn10();
1780
        }
1781
        elsif ( $format eq 'ISBN-13' ) {
1782
            $isbn = $isbn->as_isbn13();
1783
        }
1784
1785
        if ($strip_hyphens) {
1786
            $string = $isbn->as_string( [] );
1787
        } else {
1788
            $string = $isbn->as_string();
1789
        }
1790
1791
        return $string;
1792
    }
1793
}
1794
1666
=head2 GetMarcISSN
1795
=head2 GetMarcISSN
1667
1796
1668
  $marcissnsarray = GetMarcISSN( $record, $marcflavour );
1797
  $marcissnsarray = GetMarcISSN( $record, $marcflavour );
Lines 2569-2574 sub TransformMarcToKoha { Link Here
2569
        }
2698
        }
2570
    }
2699
    }
2571
2700
2701
    $result->{'isbn'} = GetNormalizedISBNsFromMarc( $record );
2702
2572
    return $result;
2703
    return $result;
2573
}
2704
}
2574
2705
(-)a/C4/ImportBatch.pm (-2 / +1 lines)
Lines 323-329 sub ModAuthInBatch { Link Here
323
323
324
=cut
324
=cut
325
325
326
sub  BatchStageMarcRecords {
326
sub BatchStageMarcRecords {
327
    my $record_type = shift;
327
    my $record_type = shift;
328
    my $encoding = shift;
328
    my $encoding = shift;
329
    my $marc_records = shift;
329
    my $marc_records = shift;
Lines 1399-1405 sub _add_biblio_fields { Link Here
1399
    my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1399
    my ($title, $author, $isbn, $issn) = _parse_biblio_fields($marc_record);
1400
    my $dbh = C4::Context->dbh;
1400
    my $dbh = C4::Context->dbh;
1401
    # FIXME no controlnumber, originalsource
1401
    # FIXME no controlnumber, originalsource
1402
    $isbn = C4::Koha::_isbn_cleanup($isbn); # FIXME C4::Koha::_isbn_cleanup should be made public
1403
    my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1402
    my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1404
    $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1403
    $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1405
    $sth->finish();
1404
    $sth->finish();
(-)a/C4/Matcher.pm (-2 / +6 lines)
Lines 630-637 sub get_matches { Link Here
630
    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
630
    $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser'));
631
    foreach my $matchpoint ( @{ $self->{'matchpoints'} } ) {
631
    foreach my $matchpoint ( @{ $self->{'matchpoints'} } ) {
632
        my @source_keys = _get_match_keys( $source_record, $matchpoint );
632
        my @source_keys = _get_match_keys( $source_record, $matchpoint );
633
633
        next if scalar(@source_keys) == 0;
634
        next if scalar(@source_keys) == 0;
634
635
636
        @source_keys = C4::Biblio::GetVariationsOfISBNs( @source_keys ) if ( $matchpoint->{index} eq 'isbn' );
637
635
        # build query
638
        # build query
636
        my $query;
639
        my $query;
637
        my $error;
640
        my $error;
Lines 640-652 sub get_matches { Link Here
640
        if ( $self->{'record_type'} eq 'biblio' ) {
643
        if ( $self->{'record_type'} eq 'biblio' ) {
641
            if ($QParser) {
644
            if ($QParser) {
642
                $query = join( " || ",
645
                $query = join( " || ",
643
                    map { "$matchpoint->{'index'}:$_" } @source_keys );
646
                    map { "$matchpoint->{'index'},phr:$_" } @source_keys );
644
            }
647
            }
645
            else {
648
            else {
646
                $query = join( " or ",
649
                $query = join( " or ",
647
                    map { "$matchpoint->{'index'}=$_" } @source_keys );
650
                    map { "$matchpoint->{'index'},phr=$_" } @source_keys );
648
            }
651
            }
649
            require C4::Search;
652
            require C4::Search;
653
650
            ( $error, $searchresults, $total_hits ) =
654
            ( $error, $searchresults, $total_hits ) =
651
              C4::Search::SimpleSearch( $query, 0, $max_matches );
655
              C4::Search::SimpleSearch( $query, 0, $max_matches );
652
        }
656
        }
(-)a/installer/data/mysql/kohastructure.sql (-5 / +5 lines)
Lines 152-158 CREATE TABLE `biblioitems` ( -- information related to bibliographic records in Link Here
152
  `volume` mediumtext,
152
  `volume` mediumtext,
153
  `number` mediumtext,
153
  `number` mediumtext,
154
  `itemtype` varchar(10) default NULL, -- biblio level item type (MARC21 942$c)
154
  `itemtype` varchar(10) default NULL, -- biblio level item type (MARC21 942$c)
155
  `isbn` varchar(30) default NULL, -- ISBN (MARC21 020$a)
155
  `isbn` varchar(255) default NULL, -- ISBN (MARC21 020$a)
156
  `issn` varchar(9) default NULL, -- ISSN (MARC21 022$a)
156
  `issn` varchar(9) default NULL, -- ISSN (MARC21 022$a)
157
  `ean` varchar(13) default NULL,
157
  `ean` varchar(13) default NULL,
158
  `publicationyear` text,
158
  `publicationyear` text,
Lines 730-736 CREATE TABLE `deletedbiblioitems` ( -- information about bibliographic records t Link Here
730
  `volume` mediumtext,
730
  `volume` mediumtext,
731
  `number` mediumtext,
731
  `number` mediumtext,
732
  `itemtype` varchar(10) default NULL, -- biblio level item type (MARC21 942$c)
732
  `itemtype` varchar(10) default NULL, -- biblio level item type (MARC21 942$c)
733
  `isbn` varchar(30) default NULL, -- ISBN (MARC21 020$a)
733
  `isbn` varchar(255) default NULL, -- ISBN (MARC21 020$a)
734
  `issn` varchar(9) default NULL, -- ISSN (MARC21 022$a)
734
  `issn` varchar(9) default NULL, -- ISSN (MARC21 022$a)
735
  `ean` varchar(13) default NULL,
735
  `ean` varchar(13) default NULL,
736
  `publicationyear` text,
736
  `publicationyear` text,
Lines 1048-1054 CREATE TABLE `import_biblios` ( Link Here
1048
  `original_source` varchar(25) default NULL,
1048
  `original_source` varchar(25) default NULL,
1049
  `title` varchar(128) default NULL,
1049
  `title` varchar(128) default NULL,
1050
  `author` varchar(80) default NULL,
1050
  `author` varchar(80) default NULL,
1051
  `isbn` varchar(30) default NULL,
1051
  `isbn` varchar(255) default NULL,
1052
  `issn` varchar(9) default NULL,
1052
  `issn` varchar(9) default NULL,
1053
  `has_items` tinyint(1) NOT NULL default 0,
1053
  `has_items` tinyint(1) NOT NULL default 0,
1054
  CONSTRAINT `import_biblios_ibfk_1` FOREIGN KEY (`import_record_id`)
1054
  CONSTRAINT `import_biblios_ibfk_1` FOREIGN KEY (`import_record_id`)
Lines 2095-2101 CREATE TABLE `suggestions` ( -- purchase suggestions Link Here
2095
  `volumedesc` varchar(255) default NULL,
2095
  `volumedesc` varchar(255) default NULL,
2096
  `publicationyear` smallint(6) default 0,
2096
  `publicationyear` smallint(6) default 0,
2097
  `place` varchar(255) default NULL, -- publication place of the suggested item
2097
  `place` varchar(255) default NULL, -- publication place of the suggested item
2098
  `isbn` varchar(30) default NULL, -- isbn of the suggested item
2098
  `isbn` varchar(255) default NULL, -- isbn of the suggested item
2099
  `mailoverseeing` smallint(1) default 0,
2099
  `mailoverseeing` smallint(1) default 0,
2100
  `biblionumber` int(11) default NULL, -- foreign key linking the suggestion to the biblio table after the suggestion has been ordered
2100
  `biblionumber` int(11) default NULL, -- foreign key linking the suggestion to the biblio table after the suggestion has been ordered
2101
  `reason` text, -- reason for accepting or rejecting the suggestion
2101
  `reason` text, -- reason for accepting or rejecting the suggestion
Lines 3030-3036 CREATE TABLE `biblioimages` ( Link Here
3030
3030
3031
DROP TABLE IF EXISTS `social_data`;
3031
DROP TABLE IF EXISTS `social_data`;
3032
CREATE TABLE IF NOT EXISTS `social_data` (
3032
CREATE TABLE IF NOT EXISTS `social_data` (
3033
  `isbn` VARCHAR(30),
3033
  `isbn` VARCHAR(255),
3034
  `num_critics` INT,
3034
  `num_critics` INT,
3035
  `num_critics_pro` INT,
3035
  `num_critics_pro` INT,
3036
  `num_quotations` INT,
3036
  `num_quotations` INT,
(-)a/installer/data/mysql/updatedatabase.pl (+12 lines)
Lines 7010-7015 CREATE TABLE IF NOT EXISTS borrower_files ( Link Here
7010
    SetVersion($DBversion);
7010
    SetVersion($DBversion);
7011
}
7011
}
7012
7012
7013
$DBversion = "3.13.00.XXX";
7014
if ( CheckVersion($DBversion) ) {
7015
    $dbh->do("ALTER TABLE biblioitems CHANGE isbn isbn VARCHAR( 255 ) NULL DEFAULT NULL");
7016
    $dbh->do("ALTER TABLE deletedbiblioitems CHANGE isbn isbn VARCHAR( 255 ) NULL DEFAULT NULL");
7017
    $dbh->do("ALTER TABLE import_biblios CHANGE isbn isbn VARCHAR( 255 ) NULL DEFAULT NULL");
7018
    $dbh->do("ALTER TABLE suggestions CHANGE isbn isbn VARCHAR( 255 ) NULL DEFAULT NULL");
7019
    $dbh->do("ALTER TABLE social_data CHANGE isbn isbn VARCHAR( 255 )");
7020
7021
    print "Upgrade to $DBversion done (Improve ISBN matching)\n";
7022
    SetVersion($DBversion);
7023
}
7024
7013
=head1 FUNCTIONS
7025
=head1 FUNCTIONS
7014
7026
7015
=head2 TableExists($table)
7027
=head2 TableExists($table)
(-)a/t/db_dependent/Biblio.t (-7 / +12 lines)
Lines 13-24 BEGIN { Link Here
13
    use_ok('C4::Biblio');
13
    use_ok('C4::Biblio');
14
}
14
}
15
15
16
my $isbn = '0590353403';
16
my @isbns = ('0491001304', '0914378260 (pbk. : v. 1) :', '0394502884 (Random House) :', 'a0877790019 (black leather)', '0456789012 (reel 1)' );
17
my $title = 'Foundation';
17
my $title = 'Foundation';
18
18
19
my $marc_record=MARC::Record->new;
19
my $marc_record = MARC::Record->new;
20
my $field = MARC::Field->new('020','','','a' => $isbn);
20
my $field;
21
$marc_record->append_fields($field);
21
22
foreach my $isbn ( @isbns ) {
23
    $field = MARC::Field->new('020','','','a' => $isbn);
24
    $marc_record->append_fields($field);
25
}
26
my $isbns_string = C4::Biblio::GetNormalizedISBNsFromMarc( $marc_record );
27
22
my($biblionumber,$biblioitemnumber) = AddBiblio($marc_record,'');
28
my($biblionumber,$biblioitemnumber) = AddBiblio($marc_record,'');
23
my $data = &GetBiblioData($biblionumber);
29
my $data = &GetBiblioData($biblionumber);
24
is($data->{Title},undef,'Makes sure title field in biblio is empty.');
30
is($data->{Title},undef,'Makes sure title field in biblio is empty.');
Lines 28-38 $marc_record->append_fields($field); Link Here
28
ModBiblio($marc_record,$biblionumber,'');
34
ModBiblio($marc_record,$biblionumber,'');
29
$data = &GetBiblioData($biblionumber);
35
$data = &GetBiblioData($biblionumber);
30
is($data->{title},$title,'uses ModBiblio to add a title to the previously created record and checks that its there.');
36
is($data->{title},$title,'uses ModBiblio to add a title to the previously created record and checks that its there.');
31
is($data->{isbn},$isbn,'Makes sure the isbn is still there after using ModBiblio.');
37
is($data->{isbn},$isbns_string,'Makes sure the isbn is still there after using ModBiblio.');
32
38
33
my $itemdata = &GetBiblioItemData($biblioitemnumber);
39
my $itemdata = &GetBiblioItemData($biblioitemnumber);
34
is($itemdata->{title},$title,'First test of GetBiblioItemData to get same result of previous two GetBiblioData tests.');
40
is($itemdata->{title},$title,'First test of GetBiblioItemData to get same result of previous two GetBiblioData tests.');
35
is($itemdata->{isbn},$isbn,'Second test checking it returns the correct isbn.');
41
is($itemdata->{isbn},$isbns_string,'Second test checking it returns the correct isbn.');
36
42
37
my $success = 0;
43
my $success = 0;
38
$field = MARC::Field->new(
44
$field = MARC::Field->new(
39
- 

Return to bug 10500