Jonathan Druart
1d23984ce3
Bug 34478: [TO SQUASH] Manual fix - admin/matching-rules Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
284 lines
10 KiB
Perl
Executable file
284 lines
10 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
#
|
|
# Copyright 2007 LibLime
|
|
#
|
|
# 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 3 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, see <http://www.gnu.org/licenses>.
|
|
#
|
|
|
|
use Modern::Perl;
|
|
|
|
use CGI qw ( -utf8 );
|
|
use C4::Auth qw( get_template_and_user );
|
|
use C4::Context;
|
|
use C4::Output qw( output_html_with_http_headers );
|
|
use C4::Matcher qw/valid_normalization_routines/;
|
|
|
|
my $script_name = "/cgi-bin/koha/admin/matching-rules.pl";
|
|
|
|
our $input = CGI->new;
|
|
my $op = $input->param('op') || '';
|
|
|
|
|
|
my ($template, $loggedinuser, $cookie)
|
|
= get_template_and_user({template_name => "admin/matching-rules.tt",
|
|
query => $input,
|
|
type => "intranet",
|
|
flagsrequired => { parameters => 'manage_matching_rules' },
|
|
});
|
|
|
|
$template->param(script_name => $script_name);
|
|
|
|
my $matcher_id = $input->param("matcher_id");
|
|
|
|
$template->param( max_matchpoint => 0 );
|
|
$template->param( max_matchcheck => 0 );
|
|
my @valid_norms = C4::Matcher::valid_normalization_routines();
|
|
unshift @valid_norms, 'none';
|
|
$template->param( valid_norms => \@valid_norms );
|
|
|
|
my $display_list = 0;
|
|
if ($op eq "edit_matching_rule") {
|
|
edit_matching_rule_form($template, $matcher_id);
|
|
} elsif ($op eq "cud-edit_matching_rule_confirmed") {
|
|
add_update_matching_rule($template, $matcher_id);
|
|
$display_list = 1;
|
|
} elsif ($op eq "add_matching_rule") {
|
|
add_matching_rule_form($template);
|
|
} elsif ($op eq "cud-add_matching_rule_confirmed") {
|
|
add_update_matching_rule($template, $matcher_id);
|
|
$display_list = 1;
|
|
} elsif ($op eq "delete_matching_rule") {
|
|
delete_matching_rule_form($template, $matcher_id);
|
|
} elsif ($op eq "cud-delete_matching_rule_confirmed") {
|
|
delete_matching_rule($template, $matcher_id);
|
|
$display_list = 1;
|
|
} else {
|
|
$display_list = 1;
|
|
}
|
|
|
|
if ($display_list) {
|
|
matching_rule_list($template);
|
|
}
|
|
|
|
output_html_with_http_headers $input, $cookie, $template->output;
|
|
|
|
exit 0;
|
|
|
|
sub add_matching_rule_form {
|
|
my $template = shift;
|
|
|
|
$template->param(
|
|
matching_rule_form => 1,
|
|
confirm_op => 'cud-add_matching_rule_confirmed',
|
|
max_matchpoint => 1,
|
|
max_matchcheck => 1
|
|
);
|
|
|
|
}
|
|
|
|
sub add_update_matching_rule {
|
|
my $template = shift;
|
|
my $matcher_id = shift;
|
|
my $record_type = $input->param('record_type') || 'biblio';
|
|
|
|
# do parsing
|
|
my $matcher = C4::Matcher->new($record_type, 1000);
|
|
$matcher->code(scalar $input->param('code'));
|
|
$matcher->description(scalar $input->param('description'));
|
|
$matcher->threshold(scalar $input->param('threshold'));
|
|
|
|
# matchpoints
|
|
my @mp_nums = sort map { /^mp_(\d+)_search_index/ ? int($1): () } $input->multi_param;
|
|
foreach my $mp_num (@mp_nums) {
|
|
my $index = $input->param("mp_${mp_num}_search_index");
|
|
my $score = $input->param("mp_${mp_num}_score");
|
|
# components
|
|
my $components = [];
|
|
my @comp_nums = sort map { /^mp_${mp_num}_c_(\d+)_tag/ ? int($1): () } $input->multi_param;
|
|
foreach my $comp_num (@comp_nums) {
|
|
my $component = {};
|
|
$component->{'tag'} = $input->param("mp_${mp_num}_c_${comp_num}_tag");
|
|
$component->{'subfields'} = $input->param("mp_${mp_num}_c_${comp_num}_subfields");
|
|
$component->{'offset'} = $input->param("mp_${mp_num}_c_${comp_num}_offset");
|
|
$component->{'length'} = $input->param("mp_${mp_num}_c_${comp_num}_length");
|
|
# norms
|
|
$component->{'norms'} = [];
|
|
my @norm_nums = sort map { /^mp_${mp_num}_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->multi_param;
|
|
foreach my $norm_num (@norm_nums) {
|
|
push @{ $component->{'norms'} }, $input->multi_param("mp_${mp_num}_c_${comp_num}_n_${norm_num}_norm");
|
|
}
|
|
push @$components, $component;
|
|
}
|
|
$matcher->add_matchpoint($index, $score, $components);
|
|
}
|
|
|
|
# match checks
|
|
my @mc_nums = sort map { /^mc_(\d+)_id/ ? int($1): () } $input->multi_param;
|
|
foreach my $mc_num (@mc_nums) {
|
|
# source components
|
|
my $src_components = [];
|
|
my @src_comp_nums = sort map { /^mc_${mc_num}_src_c_(\d+)_tag/ ? int($1): () } $input->multi_param;
|
|
foreach my $comp_num (@src_comp_nums) {
|
|
my $component = {};
|
|
$component->{'tag'} = $input->param("mc_${mc_num}_src_c_${comp_num}_tag");
|
|
$component->{'subfields'} = $input->param("mc_${mc_num}_src_c_${comp_num}_subfields");
|
|
$component->{'offset'} = $input->param("mc_${mc_num}_src_c_${comp_num}_offset");
|
|
$component->{'length'} = $input->param("mc_${mc_num}_src_c_${comp_num}_length");
|
|
# norms
|
|
$component->{'norms'} = [];
|
|
my @norm_nums = sort map { /^mc_${mc_num}_src_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->multi_param;
|
|
foreach my $norm_num (@norm_nums) {
|
|
push @{ $component->{'norms'} }, $input->multi_param("mc_${mc_num}_src_c_${comp_num}_n_${norm_num}_norm");
|
|
}
|
|
push @$src_components, $component;
|
|
}
|
|
# target components
|
|
my $tgt_components = [];
|
|
my @tgt_comp_nums = sort map { /^mc_${mc_num}_tgt_c_(\d+)_tag/ ? int($1): () } $input->multi_param;
|
|
foreach my $comp_num (@tgt_comp_nums) {
|
|
my $component = {};
|
|
$component->{'tag'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_tag");
|
|
$component->{'subfields'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_subfields");
|
|
$component->{'offset'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_offset");
|
|
$component->{'length'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_length");
|
|
# norms
|
|
$component->{'norms'} = [];
|
|
my @norm_nums = sort map { /^mc_${mc_num}_tgt_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->multi_param;
|
|
foreach my $norm_num (@norm_nums) {
|
|
push @{ $component->{'norms'} }, $input->multi_param("mc_${mc_num}_tgt_c_${comp_num}_n_${norm_num}_norm");
|
|
}
|
|
push @$tgt_components, $component;
|
|
}
|
|
$matcher->add_required_check($src_components, $tgt_components);
|
|
}
|
|
|
|
if (defined $matcher_id and $matcher_id =~ /^\d+/) {
|
|
$matcher->_id($matcher_id);
|
|
$template->param(edited_matching_rule => $matcher->code());
|
|
} else {
|
|
$template->param(added_matching_rule => $matcher->code());
|
|
}
|
|
$matcher_id = $matcher->store();
|
|
}
|
|
|
|
sub delete_matching_rule_form {
|
|
my $template = shift;
|
|
my $matcher_id = shift;
|
|
|
|
my $matcher = C4::Matcher->fetch($matcher_id);
|
|
$template->param(
|
|
delete_matching_rule_form => 1,
|
|
confirm_op => "cud-delete_matching_rule_confirmed",
|
|
matcher_id => $matcher_id,
|
|
code => $matcher->code(),
|
|
description => $matcher->description(),
|
|
);
|
|
}
|
|
|
|
sub delete_matching_rule {
|
|
my $template = shift;
|
|
my $matcher_id = shift;
|
|
|
|
my $matcher = C4::Matcher->fetch($matcher_id);
|
|
$template->param(deleted_matching_rule => $matcher->code(),
|
|
);
|
|
C4::Matcher->delete($matcher_id);
|
|
}
|
|
|
|
sub edit_matching_rule_form {
|
|
my $template = shift;
|
|
my $matcher_id = shift;
|
|
|
|
my $matcher = C4::Matcher->fetch($matcher_id);
|
|
|
|
$template->{VARS}->{'matcher_id'} = $matcher_id;
|
|
$template->{VARS}->{'code'} = $matcher->code();
|
|
$template->{VARS}->{'description'} = $matcher->description();
|
|
$template->{VARS}->{'threshold'} = $matcher->threshold();
|
|
$template->{VARS}->{'record_type'} = $matcher->record_type();
|
|
|
|
my $matcher_info = $matcher->dump();
|
|
my @matchpoints = ();
|
|
my $mp_num = 0;
|
|
foreach my $matchpoint (@{ $matcher_info->{'matchpoints'} }) {
|
|
$mp_num++;
|
|
my @components = _parse_components($matchpoint->{'components'});
|
|
push @matchpoints, {
|
|
mp_num => $mp_num,
|
|
index => $matchpoint->{'index'},
|
|
score => $matchpoint->{'score'},
|
|
components => \@components
|
|
};
|
|
}
|
|
$template->param(matchpoints => \@matchpoints);
|
|
|
|
my $mc_num = 0;
|
|
my @matchchecks = ();
|
|
foreach my $matchcheck (@{ $matcher_info->{'matchchecks'} }) {
|
|
$mc_num++;
|
|
my @src_components = _parse_components($matchcheck->{'source_matchpoint'}->{'components'});
|
|
my @tgt_components = _parse_components($matchcheck->{'target_matchpoint'}->{'components'});
|
|
push @matchchecks, {
|
|
mc_num => $mc_num,
|
|
src_components => \@src_components,
|
|
tgt_components => \@tgt_components
|
|
};
|
|
}
|
|
$template->param(matchchecks => \@matchchecks);
|
|
|
|
$template->param(
|
|
matching_rule_form => 1,
|
|
edit_matching_rule => 1,
|
|
confirm_op => 'cud-edit_matching_rule_confirmed',
|
|
max_matchpoint => $mp_num,
|
|
max_matchcheck => $mc_num
|
|
);
|
|
|
|
}
|
|
|
|
sub _parse_components {
|
|
my $components_ref = shift;
|
|
my @components = ();
|
|
|
|
my $comp_num = 0;
|
|
foreach my $component (@{ $components_ref }) {
|
|
$comp_num++;
|
|
my $norm_num = 0;
|
|
my @norms;
|
|
foreach my $norm (@{ $component->{'norms'} }) {
|
|
$norm_num++;
|
|
push @norms, { norm_num => $norm_num, norm => $norm };
|
|
}
|
|
push @components, {
|
|
comp_num => $comp_num,
|
|
tag => $component->{'tag'},
|
|
subfields => join("", sort keys %{ $component->{'subfields'} }),
|
|
offset => $component->{'offset'},
|
|
'length' => $component->{'length'},
|
|
norms => \@norms
|
|
};
|
|
}
|
|
|
|
return @components;
|
|
}
|
|
|
|
sub matching_rule_list {
|
|
my $template = shift;
|
|
|
|
my @matching_rules = C4::Matcher::GetMatcherList();
|
|
$template->param(available_matching_rules => \@matching_rules);
|
|
$template->param(display_list => 1);
|
|
}
|