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

(-)a/Koha/Biblio.pm (-35 / +111 lines)
Lines 1019-1071 sub to_api_mapping { Link Here
1019
=cut
1019
=cut
1020
1020
1021
sub get_marc_host {
1021
sub get_marc_host {
1022
    my ($self, $params) = @_;
1022
    my ( $self, $params ) = @_;
1023
    my $no_items = $params->{no_items};
1023
    my $no_items = $params->{no_items};
1024
    return if C4::Context->preference('marcflavour') eq 'UNIMARC'; # TODO
1024
    return if C4::Context->preference('marcflavour') eq 'UNIMARC';    # TODO
1025
    return if $params->{no_items} && $self->items->count > 0;
1025
    return if $params->{no_items} && $self->items->count > 0;
1026
1026
1027
    my $record;
1027
    my ( $bibno, $hostfld );
1028
    eval { $record = $self->metadata->record };
1028
    my $engine = Koha::SearchEngine::Search->new(
1029
    return if !$record;
1029
        { index => $Koha::SearchEngine::BIBLIOS_INDEX } );
1030
1030
1031
    # We pick the first $w with your MARCOrgCode or the first $w that has no
1031
    # Search for host with/without orgcode
1032
    # code (between parentheses) at all.
1032
    my $queries = $self->get_host_queries;
1033
    my $orgcode = C4::Context->preference('MARCOrgCode') // q{};
1033
    for my $query ( @{$queries} ) {
1034
    my $hostfld;
1034
        my ( $error, $results, $total_hits ) =
1035
    foreach my $f ( $record->field('773') ) {
1035
          $engine->simple_search_compat( $query->{query}, 0, 1 );
1036
        my $w = $f->subfield('w') or next;
1036
1037
        if( $w =~ /^\($orgcode\)\s*(\d+)/i or $w =~ /^\d+/ ) {
1037
        if ( !$error and $total_hits == 1 ) {
1038
            $hostfld = $f;
1038
            $bibno   = $engine->extract_biblionumber( $results->[0] );
1039
            last;
1039
            $hostfld = $query->{field};
1040
        }
1041
    }
1042
    return if !$hostfld;
1043
    my $rcn = $hostfld->subfield('w');
1044
1045
    # Look for control number with/without orgcode
1046
    my $engine = Koha::SearchEngine::Search->new({ index => $Koha::SearchEngine::BIBLIOS_INDEX });
1047
    my $bibno;
1048
    for my $try (1..2) {
1049
        my ( $error, $results, $total_hits ) = $engine->simple_search_compat( 'Control-number='.$rcn, 0,1 );
1050
        if( !$error and $total_hits == 1 ) {
1051
            $bibno = $engine->extract_biblionumber( $results->[0] );
1052
            last;
1053
        }
1054
        # Add or remove orgcode for second try
1055
        if( $try == 1 && $rcn =~ /\)\s*(\d+)/ ) {
1056
            $rcn = $1; # number only
1057
        } elsif( $try == 1 && $rcn =~ /^\d+/ ) {
1058
            $rcn = "($orgcode)$rcn";
1059
        } else {
1060
            last;
1040
            last;
1061
        }
1041
        }
1062
    }
1042
    }
1063
    if( $bibno ) {
1043
1044
    if ($bibno) {
1064
        my $host = Koha::Biblios->find($bibno) or return;
1045
        my $host = Koha::Biblios->find($bibno) or return;
1065
        return wantarray ? ( $host, $hostfld->subfield('g') ) : $host;
1046
        return wantarray ? ( $host, $hostfld->subfield('g') ) : $host;
1066
    }
1047
    }
1067
}
1048
}
1068
1049
1050
=head2 get_host_queries
1051
1052
Returns an array of queries which can be used to search for the host of this MARC21 biblio.
1053
1054
The array is in most specific to least specific search order.
1055
1056
The algorithm used to construct the search query is:
1057
1. Iterate through all `773` fields.
1058
2. If using 'UseControlNumber' iterate through each `w` subfield.
1059
2a. Best match is where the $w contains `(cni)cn` and the cni matches our orgcode.
1060
2b. Next best match is where $w contains `(cni)cn` and the cni does not match our orgcode.
1061
2c. Subsequent matches are where $w contains just `cn`
1062
3. If not using 'UseControlNumber' we search on title and author
1063
1064
=cut
1065
1066
sub get_host_queries {
1067
    my ($self) = @_;
1068
1069
    my $record = $self->metadata->record;
1070
1071
    my $builder = Koha::SearchEngine::QueryBuilder->new(
1072
        { index => $Koha::SearchEngine::BIBLIOS_INDEX } );
1073
    my $cni_queries = [];
1074
    my $cn_queries  = [];
1075
    my $ti_queries  = [];
1076
1077
    my $orgcode = C4::Context->preference('MARCOrgCode') // q{};
1078
    foreach my $f ( $record->field('773') ) {
1079
        if ( C4::Context->preference('UseControlNumber') ) {
1080
            foreach my $w ( $f->subfield('w') ) {
1081
1082
                # Control-number-identifier prepended
1083
                if ( $w =~ /^\((?<cni>.*)\)\s*(?<cn>\d+)/i ) {
1084
1085
                    # Local orgcode match
1086
                    if ( $+{cni} eq $orgcode ) {
1087
                        my $query =
1088
                            "(Control-number:"
1089
                          . $+{cn}
1090
                          . " AND cni:"
1091
                          . $+{cni} . ")";
1092
                        unshift(
1093
                            @{$cni_queries},
1094
                            { query => $query, field => $f }
1095
                        );
1096
                    }
1097
1098
                    # Other orgcodes
1099
                    else {
1100
                        my $query =
1101
                            "(Control-number:"
1102
                          . $+{cn}
1103
                          . " AND cni:"
1104
                          . $+{cni} . ")";
1105
                        push(
1106
                            @{$cni_queries},
1107
                            {
1108
                                query => $query,
1109
                                field => $f
1110
                            }
1111
                        );
1112
                    }
1113
                }
1114
1115
                # Control-number only
1116
                elsif ( $w =~ /^(?<cn>\d+)/ ) {
1117
                    my $query = "(Control-number:" . $+{cn} . ")";
1118
                    push(
1119
                        @{$cn_queries},
1120
                        {
1121
                            query => $query,
1122
                            field => $f
1123
                        }
1124
                    );
1125
                }
1126
            }
1127
        }
1128
        else {
1129
            my $searchstr;
1130
            my $cleaned_title = $f->subfield('t');
1131
            $cleaned_title =~ tr|/||;
1132
            $cleaned_title = $builder->clean_search_term($cleaned_title);
1133
            $searchstr     = "ti,phr:($cleaned_title)";
1134
            my $cleaned_author = $f->subfield('a');
1135
            $cleaned_author =~ tr|/||;
1136
            $cleaned_author = $builder->clean_search_term($cleaned_author);
1137
            $searchstr .= " AND au:($cleaned_author)" if $cleaned_author;
1138
            push( @{$ti_queries}, { query => $searchstr, field => $f } );
1139
        }
1140
    }
1141
1142
    return [ @{$cni_queries}, @{$cn_queries}, @{$ti_queries} ];
1143
}
1144
1069
=head2 Internal methods
1145
=head2 Internal methods
1070
1146
1071
=head3 type
1147
=head3 type
(-)a/t/db_dependent/Koha/Biblio.t (-1 / +32 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 19;
20
use Test::More tests => 20;
21
use Test::Warn;
21
use Test::Warn;
22
22
23
use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc );
23
use C4::Biblio qw( AddBiblio ModBiblio ModBiblioMarc );
Lines 564-569 subtest 'get_marc_components() tests' => sub { Link Here
564
    $schema->storage->txn_rollback;
564
    $schema->storage->txn_rollback;
565
};
565
};
566
566
567
subtest 'get_host_queries' => sub {
568
    plan tests => 4;
569
570
    my $biblio = $builder->build_sample_biblio();
571
    my $biblionumber = $biblio->biblionumber;
572
    my $record = $biblio->metadata->record;
573
574
    my $marc_773_field = MARC::Field->new('773', '0', '#', 'a' => 'J. K Rowling', 't' => 'The Tales of Beedle the Bard', 'w' => '12345' );
575
    $record->append_fields($marc_773_field);
576
    C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
577
    $biblio = Koha::Biblios->find( $biblio->biblionumber);
578
579
    t::lib::Mocks::mock_preference( 'UseControlNumber', '0' );
580
    my $queries = $biblio->get_host_queries;
581
    is($queries->[0]->{query}, "ti,phr:(The Tales of Beedle the Bard) AND au:(J. K Rowling)", "UseControlNumber disabled");
582
583
    t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
584
585
    $queries = $biblio->get_host_queries;
586
    is($queries->[0]->{query}, "(Control-number:12345)", "UseControlNumber enabled without MarcOrgCode");
587
588
    $marc_773_field = MARC::Field->new('773', '0', '#', 'a' => 'J. K Rowling', 't' => 'The Tales of Beedle the Bard', 'w' => '(OSt)23456' );
589
    $record->append_fields($marc_773_field);
590
    C4::Biblio::ModBiblio( $record, $biblio->biblionumber );
591
    $biblio = Koha::Biblios->find( $biblio->biblionumber);
592
593
    $queries = $biblio->get_host_queries;
594
    is($queries->[0]->{query}, "(Control-number:23456 AND cni:OSt)", "UseControlNumber enabled with MarcOrgCode comes out first");
595
    is($queries->[1]->{query}, "(Control-number:12345)", "UseControlNumber enabled without MarcOrgCode comes out second");
596
};
597
567
subtest 'get_components_query' => sub {
598
subtest 'get_components_query' => sub {
568
    plan tests => 3;
599
    plan tests => 3;
569
600
(-)a/t/db_dependent/Koha/Biblio/host_record.t (-1 / +1 lines)
Lines 40-45 subtest 'get_marc_host' => sub { Link Here
40
40
41
    t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
41
    t::lib::Mocks::mock_preference( 'marcflavour', 'MARC21' );
42
    t::lib::Mocks::mock_preference( 'MARCOrgCode', 'xyz' );
42
    t::lib::Mocks::mock_preference( 'MARCOrgCode', 'xyz' );
43
    t::lib::Mocks::mock_preference( 'UseControlNumber', '1' );
43
44
44
    my $bib1 = $builder->build_object({ class => 'Koha::Biblios' });
45
    my $bib1 = $builder->build_object({ class => 'Koha::Biblios' });
45
    my $bib2 = $builder->build_object({ class => 'Koha::Biblios' });
46
    my $bib2 = $builder->build_object({ class => 'Koha::Biblios' });
46
- 

Return to bug 29268