X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FMatcher.pm;h=77716f736cc54cbd9b1a8a3eacdcd11c5fc6d84c;hb=abbcf684c272239d3bf891160e2c59f3855c195d;hp=8b82911a2349300ca8bb5e275c9b19c21757f029;hpb=ce1b79d55d421d6d173d644ee7061ebb5b93919a;p=koha-ffzg.git diff --git a/C4/Matcher.pm b/C4/Matcher.pm index 8b82911a23..77716f736c 100644 --- a/C4/Matcher.pm +++ b/C4/Matcher.pm @@ -19,12 +19,17 @@ package C4::Matcher; use Modern::Perl; -use MARC::Record; use Koha::SearchEngine; use Koha::SearchEngine::Search; use Koha::SearchEngine::QueryBuilder; -use Koha::Util::Normalize qw/legacy_default remove_spaces upper_case lower_case/; +use Koha::Util::Normalize qw( + ISBN + legacy_default + lower_case + remove_spaces + upper_case +); =head1 NAME @@ -165,7 +170,7 @@ sub fetch { $sth->execute($id); my $row = $sth->fetchrow_hashref; $sth->finish(); - return undef unless defined $row; + return unless defined $row; my $self = {}; $self->{'id'} = $row->{'matcher_id'}; @@ -622,26 +627,18 @@ sub get_matches { my $matches = {}; - my $QParser; - $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); foreach my $matchpoint ( @{ $self->{'matchpoints'} } ) { my @source_keys = _get_match_keys( $source_record, $matchpoint ); next if scalar(@source_keys) == 0; - # FIXME - because of a bug in QueryParser, an expression ofthe - # format 'isbn:"isbn1" || isbn:"isbn2" || isbn"isbn3"...' - # does not get parsed correctly, so we will not - # do AggressiveMatchOnISBN if UseQueryParser is on @source_keys = C4::Koha::GetVariationsOfISBNs(@source_keys) if ( $matchpoint->{index} =~ /^isbn$/i - && C4::Context->preference('AggressiveMatchOnISBN') ) - && !C4::Context->preference('UseQueryParser'); + && C4::Context->preference('AggressiveMatchOnISBN') ); @source_keys = C4::Koha::GetVariationsOfISSNs(@source_keys) if ( $matchpoint->{index} =~ /^issn$/i - && C4::Context->preference('AggressiveMatchOnISSN') ) - && !C4::Context->preference('UseQueryParser'); + && C4::Context->preference('AggressiveMatchOnISSN') ); # build query my $query; @@ -650,18 +647,10 @@ sub get_matches { my $total_hits; if ( $self->{'record_type'} eq 'biblio' ) { - #NOTE: The QueryParser can't handle the CCL syntax of 'qualifier','qualifier', so fallback to non-QueryParser. - #NOTE: You can see this in C4::Search::SimpleSearch() as well in a different way. - if ($QParser && $matchpoint->{'index'} !~ m/\w,\w/) { - $query = join( " || ", - map { "$matchpoint->{'index'}:$_" } @source_keys ); - } - else { - my $phr = ( C4::Context->preference('AggressiveMatchOnISBN') || C4::Context->preference('AggressiveMatchOnISSN') ) ? ',phr' : q{}; - $query = join( " OR ", - map { "$matchpoint->{'index'}$phr=\"$_\"" } @source_keys ); - #NOTE: double-quote the values so you don't get a "Embedded truncation not supported" error when a term has a ? in it. - } + my $phr = ( C4::Context->preference('AggressiveMatchOnISBN') || C4::Context->preference('AggressiveMatchOnISSN') ) ? ',phr' : q{}; + $query = join( " OR ", + map { "$matchpoint->{'index'}$phr=\"$_\"" } @source_keys ); + #NOTE: double-quote the values so you don't get a "Embedded truncation not supported" error when a term has a ? in it. # Use state variables to avoid recreating the objects every time. # With Elasticsearch this also avoids creating a massive amount of @@ -726,7 +715,7 @@ sub get_matches { # get rid of any that don't meet the required checks $matches = { map { - _passes_required_checks( $source_record, $_, $self->{'required_checks'} ) + _passes_required_checks( $source_record, $matches->{$_}->{'record'}, $self->{'required_checks'} ) ? ( $_ => $matches->{$_} ) : () } keys %$matches @@ -790,8 +779,7 @@ sub dump { } sub _passes_required_checks { - my ($source_record, $target_blob, $matchchecks) = @_; - my $target_record = MARC::Record->new_from_usmarc($target_blob); # FIXME -- need to avoid parsing record twice + my ($source_record, $target_record, $matchchecks) = @_; # no checks supplied == automatic pass return 1 if $#{ $matchchecks } == -1; @@ -829,18 +817,33 @@ sub _get_match_keys { for (my $i = 0; $i <= $#{ $matchpoint->{'components'} }; $i++) { my $component = $matchpoint->{'components'}->[$i]; my $j = -1; - FIELD: foreach my $field ($source_record->field($component->{'tag'})) { + + my @fields = (); + my $tag = $component->{'tag'}; + if ($tag && $tag eq 'LDR'){ + $fields[0] = $source_record->leader(); + } + else { + @fields = $source_record->field($tag); + } + + FIELD: foreach my $field (@fields) { $j++; last FIELD if $j > 0 and $check_only_first_repeat; last FIELD if $i > 0 and $j > $#keys; my $string; - if ( $field->is_control_field() ) { + if ( ! ref $field ){ + $string = "$field"; + } + elsif ( $field->is_control_field() ) { $string = $field->data(); - } else { + } elsif ( defined $component->{subfields} && keys %{$component->{subfields}} ){ $string = $field->as_string( join('', keys %{ $component->{ subfields } }), ' ' # ' ' as separator ); + } else { + $string = $field->as_string(); } if ($component->{'length'}>0) { @@ -866,6 +869,9 @@ sub _get_match_keys { elsif ( $norm eq 'legacy_default' ) { $key = legacy_default($key); } + elsif ( $norm eq 'ISBN' ) { + $key = ISBN($key); + } } else { warn "Invalid normalization routine required ($norm)" unless $norm eq 'none'; @@ -902,7 +908,8 @@ sub valid_normalization_routines { 'remove_spaces', 'upper_case', 'lower_case', - 'legacy_default' + 'legacy_default', + 'ISBN' ); }