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 |