3 # Copyright 2007 LibLime
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
28 use C4
::Matcher qw
/valid_normalization_routines/;
30 my $script_name = "/cgi-bin/koha/admin/matching-rules.pl";
33 my $op = $input->param('op') || '';
36 my ($template, $loggedinuser, $cookie)
37 = get_template_and_user
({template_name
=> "admin/matching-rules.tt",
41 flagsrequired
=> { parameters
=> 'manage_matching_rules' },
45 $template->param(script_name
=> $script_name);
47 my $matcher_id = $input->param("matcher_id");
49 $template->param( max_matchpoint
=> 0 );
50 $template->param( max_matchcheck
=> 0 );
51 my @valid_norms = C4
::Matcher
::valid_normalization_routines
();
52 unshift @valid_norms, 'none';
53 $template->param( valid_norms
=> \
@valid_norms );
56 if ($op eq "edit_matching_rule") {
57 edit_matching_rule_form
($template, $matcher_id);
58 } elsif ($op eq "edit_matching_rule_confirmed") {
59 add_update_matching_rule
($template, $matcher_id);
61 } elsif ($op eq "add_matching_rule") {
62 add_matching_rule_form
($template);
63 } elsif ($op eq "add_matching_rule_confirmed") {
64 add_update_matching_rule
($template, $matcher_id);
66 } elsif ($op eq "delete_matching_rule") {
67 delete_matching_rule_form
($template, $matcher_id);
68 } elsif ($op eq "delete_matching_rule_confirmed") {
69 delete_matching_rule
($template, $matcher_id);
76 matching_rule_list
($template);
79 output_html_with_http_headers
$input, $cookie, $template->output;
83 sub add_matching_rule_form
{
87 matching_rule_form
=> 1,
88 confirm_op
=> 'add_matching_rule_confirmed',
95 sub add_update_matching_rule
{
97 my $matcher_id = shift;
98 my $record_type = $input->param('record_type') || 'biblio';
101 my $matcher = C4
::Matcher
->new($record_type, 1000);
102 $matcher->code(scalar $input->param('code'));
103 $matcher->description(scalar $input->param('description'));
104 $matcher->threshold(scalar $input->param('threshold'));
107 my @mp_nums = sort map { /^mp_(\d+)_search_index/ ?
int($1): () } $input->multi_param;
108 foreach my $mp_num (@mp_nums) {
109 my $index = $input->param("mp_${mp_num}_search_index");
110 my $score = $input->param("mp_${mp_num}_score");
113 my @comp_nums = sort map { /^mp_${mp_num}_c_(\d+)_tag/ ?
int($1): () } $input->multi_param;
114 foreach my $comp_num (@comp_nums) {
116 $component->{'tag'} = $input->param("mp_${mp_num}_c_${comp_num}_tag");
117 $component->{'subfields'} = $input->param("mp_${mp_num}_c_${comp_num}_subfields");
118 $component->{'offset'} = $input->param("mp_${mp_num}_c_${comp_num}_offset");
119 $component->{'length'} = $input->param("mp_${mp_num}_c_${comp_num}_length");
121 $component->{'norms'} = [];
122 my @norm_nums = sort map { /^mp_${mp_num}_c_${comp_num}_n_(\d+)_norm/ ?
int($1): () } $input->multi_param;
123 foreach my $norm_num (@norm_nums) {
124 push @
{ $component->{'norms'} }, $input->multi_param("mp_${mp_num}_c_${comp_num}_n_${norm_num}_norm");
126 push @
$components, $component;
128 $matcher->add_matchpoint($index, $score, $components);
132 my @mc_nums = sort map { /^mc_(\d+)_id/ ?
int($1): () } $input->multi_param;
133 foreach my $mc_num (@mc_nums) {
135 my $src_components = [];
136 my @src_comp_nums = sort map { /^mc_${mc_num}_src_c_(\d+)_tag/ ?
int($1): () } $input->multi_param;
137 foreach my $comp_num (@src_comp_nums) {
139 $component->{'tag'} = $input->param("mc_${mc_num}_src_c_${comp_num}_tag");
140 $component->{'subfields'} = $input->param("mc_${mc_num}_src_c_${comp_num}_subfields");
141 $component->{'offset'} = $input->param("mc_${mc_num}_src_c_${comp_num}_offset");
142 $component->{'length'} = $input->param("mc_${mc_num}_src_c_${comp_num}_length");
144 $component->{'norms'} = [];
145 my @norm_nums = sort map { /^mc_${mc_num}_src_c_${comp_num}_n_(\d+)_norm/ ?
int($1): () } $input->multi_param;
146 foreach my $norm_num (@norm_nums) {
147 push @
{ $component->{'norms'} }, $input->multi_param("mc_${mc_num}_src_c_${comp_num}_n_${norm_num}_norm");
149 push @
$src_components, $component;
152 my $tgt_components = [];
153 my @tgt_comp_nums = sort map { /^mc_${mc_num}_tgt_c_(\d+)_tag/ ?
int($1): () } $input->multi_param;
154 foreach my $comp_num (@tgt_comp_nums) {
156 $component->{'tag'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_tag");
157 $component->{'subfields'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_subfields");
158 $component->{'offset'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_offset");
159 $component->{'length'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_length");
161 $component->{'norms'} = [];
162 my @norm_nums = sort map { /^mc_${mc_num}_tgt_c_${comp_num}_n_(\d+)_norm/ ?
int($1): () } $input->multi_param;
163 foreach my $norm_num (@norm_nums) {
164 push @
{ $component->{'norms'} }, $input->multi_param("mc_${mc_num}_tgt_c_${comp_num}_n_${norm_num}_norm");
166 push @
$tgt_components, $component;
168 $matcher->add_required_check($src_components, $tgt_components);
171 if (defined $matcher_id and $matcher_id =~ /^\d+/) {
172 $matcher->_id($matcher_id);
173 $template->param(edited_matching_rule
=> $matcher->code());
175 $template->param(added_matching_rule
=> $matcher->code());
177 $matcher_id = $matcher->store();
180 sub delete_matching_rule_form
{
181 my $template = shift;
182 my $matcher_id = shift;
184 my $matcher = C4
::Matcher
->fetch($matcher_id);
186 delete_matching_rule_form
=> 1,
187 confirm_op
=> "delete_matching_rule_confirmed",
188 matcher_id
=> $matcher_id,
189 code
=> $matcher->code(),
190 description
=> $matcher->description(),
194 sub delete_matching_rule
{
195 my $template = shift;
196 my $matcher_id = shift;
198 my $matcher = C4
::Matcher
->fetch($matcher_id);
199 $template->param(deleted_matching_rule
=> $matcher->code(),
201 C4
::Matcher
->delete($matcher_id);
204 sub edit_matching_rule_form
{
205 my $template = shift;
206 my $matcher_id = shift;
208 my $matcher = C4
::Matcher
->fetch($matcher_id);
210 $template->{VARS
}->{'matcher_id'} = $matcher_id;
211 $template->{VARS
}->{'code'} = $matcher->code();
212 $template->{VARS
}->{'description'} = $matcher->description();
213 $template->{VARS
}->{'threshold'} = $matcher->threshold();
214 $template->{VARS
}->{'record_type'} = $matcher->record_type();
216 my $matcher_info = $matcher->dump();
217 my @matchpoints = ();
219 foreach my $matchpoint (@
{ $matcher_info->{'matchpoints'} }) {
221 my @components = _parse_components
($matchpoint->{'components'});
224 index => $matchpoint->{'index'},
225 score
=> $matchpoint->{'score'},
226 components
=> \
@components
229 $template->param(matchpoints
=> \
@matchpoints);
232 my @matchchecks = ();
233 foreach my $matchcheck (@
{ $matcher_info->{'matchchecks'} }) {
235 my @src_components = _parse_components
($matchcheck->{'source_matchpoint'}->{'components'});
236 my @tgt_components = _parse_components
($matchcheck->{'target_matchpoint'}->{'components'});
239 src_components
=> \
@src_components,
240 tgt_components
=> \
@tgt_components
243 $template->param(matchchecks
=> \
@matchchecks);
246 matching_rule_form
=> 1,
247 edit_matching_rule
=> 1,
248 confirm_op
=> 'edit_matching_rule_confirmed',
249 max_matchpoint
=> $mp_num,
250 max_matchcheck
=> $mc_num
255 sub _parse_components
{
256 my $components_ref = shift;
260 foreach my $component (@
{ $components_ref }) {
264 foreach my $norm (@
{ $component->{'norms'} }) {
266 push @norms, { norm_num
=> $norm_num, norm
=> $norm };
269 comp_num
=> $comp_num,
270 tag
=> $component->{'tag'},
271 subfields
=> join("", sort keys %{ $component->{'subfields'} }),
272 offset
=> $component->{'offset'},
273 'length' => $component->{'length'},
281 sub matching_rule_list
{
282 my $template = shift;
284 my @matching_rules = C4
::Matcher
::GetMatcherList
();
285 $template->param(available_matching_rules
=> \
@matching_rules);
286 $template->param(display_list
=> 1);