Bug 14639: (regression tests) Extend Koha::MetadataRecord to handle serialization...
[koha.git] / admin / matching-rules.pl
blob8753f0fd0a607da5fab3d27acdafef7eba8a6514
1 #! /usr/bin/perl
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>.
21 use strict;
22 use warnings;
24 use CGI qw ( -utf8 );
25 use C4::Auth;
26 use C4::Context;
27 use C4::Output;
28 use C4::Koha;
29 use C4::Matcher;
31 my $script_name = "/cgi-bin/koha/admin/matching-rules.pl";
33 our $input = new CGI;
34 my $op = $input->param('op') || '';
37 my ($template, $loggedinuser, $cookie)
38 = get_template_and_user({template_name => "admin/matching-rules.tt",
39 query => $input,
40 type => "intranet",
41 authnotrequired => 0,
42 flagsrequired => {parameters => 'parameters_remaining_permissions'},
43 debug => 1,
44 });
46 $template->param(script_name => $script_name);
48 my $matcher_id = $input->param("matcher_id");
50 $template->param(max_matchpoint => 0);
51 $template->param(max_matchcheck => 0);
52 my $display_list = 0;
53 if ($op eq "edit_matching_rule") {
54 edit_matching_rule_form($template, $matcher_id);
55 } elsif ($op eq "edit_matching_rule_confirmed") {
56 add_update_matching_rule($template, $matcher_id);
57 $display_list = 1;
58 } elsif ($op eq "add_matching_rule") {
59 add_matching_rule_form($template);
60 } elsif ($op eq "add_matching_rule_confirmed") {
61 add_update_matching_rule($template, $matcher_id);
62 $display_list = 1;
63 } elsif ($op eq "delete_matching_rule") {
64 delete_matching_rule_form($template, $matcher_id);
65 } elsif ($op eq "delete_matching_rule_confirmed") {
66 delete_matching_rule($template, $matcher_id);
67 $display_list = 1;
68 } else {
69 $display_list = 1;
72 if ($display_list) {
73 matching_rule_list($template);
76 output_html_with_http_headers $input, $cookie, $template->output;
78 exit 0;
80 sub add_matching_rule_form {
81 my $template = shift;
83 $template->param(
84 matching_rule_form => 1,
85 confirm_op => 'add_matching_rule_confirmed',
86 max_matchpoint => 1,
87 max_matchcheck => 1
92 sub add_update_matching_rule {
93 my $template = shift;
94 my $matcher_id = shift;
95 my $record_type = $input->param('record_type') || 'biblio';
97 # do parsing
98 my $matcher = C4::Matcher->new($record_type, 1000);
99 $matcher->code($input->param('code'));
100 $matcher->description($input->param('description'));
101 $matcher->threshold($input->param('threshold'));
103 # matchpoints
104 my @mp_nums = sort map { /^mp_(\d+)_search_index/ ? int($1): () } $input->param;
105 foreach my $mp_num (@mp_nums) {
106 my $index = $input->param("mp_${mp_num}_search_index");
107 my $score = $input->param("mp_${mp_num}_score");
108 # components
109 my $components = [];
110 my @comp_nums = sort map { /^mp_${mp_num}_c_(\d+)_tag/ ? int($1): () } $input->param;
111 foreach my $comp_num (@comp_nums) {
112 my $component = {};
113 $component->{'tag'} = $input->param("mp_${mp_num}_c_${comp_num}_tag");
114 $component->{'subfields'} = $input->param("mp_${mp_num}_c_${comp_num}_subfields");
115 $component->{'offset'} = $input->param("mp_${mp_num}_c_${comp_num}_offset");
116 $component->{'length'} = $input->param("mp_${mp_num}_c_${comp_num}_length");
117 # norms
118 $component->{'norms'} = [];
119 my @norm_nums = sort map { /^mp_${mp_num}_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
120 foreach my $norm_num (@norm_nums) {
121 push @{ $component->{'norms'} }, $input->param("mp_${mp_num}_c_${comp_num}_n_${norm_num}_norm");
123 push @$components, $component;
125 $matcher->add_matchpoint($index, $score, $components);
128 # match checks
129 my @mc_nums = sort map { /^mc_(\d+)_id/ ? int($1): () } $input->param;
130 foreach my $mc_num (@mc_nums) {
131 # source components
132 my $src_components = [];
133 my @src_comp_nums = sort map { /^mc_${mc_num}_src_c_(\d+)_tag/ ? int($1): () } $input->param;
134 foreach my $comp_num (@src_comp_nums) {
135 my $component = {};
136 $component->{'tag'} = $input->param("mc_${mc_num}_src_c_${comp_num}_tag");
137 $component->{'subfields'} = $input->param("mc_${mc_num}_src_c_${comp_num}_subfields");
138 $component->{'offset'} = $input->param("mc_${mc_num}_src_c_${comp_num}_offset");
139 $component->{'length'} = $input->param("mc_${mc_num}_src_c_${comp_num}_length");
140 # norms
141 $component->{'norms'} = [];
142 my @norm_nums = sort map { /^mc_${mc_num}_src_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
143 foreach my $norm_num (@norm_nums) {
144 push @{ $component->{'norms'} }, $input->param("mc_${mc_num}_src_c_${comp_num}_n_${norm_num}_norm");
146 push @$src_components, $component;
148 # target components
149 my $tgt_components = [];
150 my @tgt_comp_nums = sort map { /^mc_${mc_num}_tgt_c_(\d+)_tag/ ? int($1): () } $input->param;
151 foreach my $comp_num (@tgt_comp_nums) {
152 my $component = {};
153 $component->{'tag'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_tag");
154 $component->{'subfields'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_subfields");
155 $component->{'offset'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_offset");
156 $component->{'length'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_length");
157 # norms
158 $component->{'norms'} = [];
159 my @norm_nums = sort map { /^mc_${mc_num}_tgt_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
160 foreach my $norm_num (@norm_nums) {
161 push @{ $component->{'norms'} }, $input->param("mc_${mc_num}_tgt_c_${comp_num}_n_${norm_num}_norm");
163 push @$tgt_components, $component;
165 $matcher->add_required_check($src_components, $tgt_components);
168 if (defined $matcher_id and $matcher_id =~ /^\d+/) {
169 $matcher->_id($matcher_id);
170 $template->param(edited_matching_rule => $matcher->code());
171 } else {
172 $template->param(added_matching_rule => $matcher->code());
174 $matcher_id = $matcher->store();
177 sub delete_matching_rule_form {
178 my $template = shift;
179 my $matcher_id = shift;
181 my $matcher = C4::Matcher->fetch($matcher_id);
182 $template->param(
183 delete_matching_rule_form => 1,
184 confirm_op => "delete_matching_rule_confirmed",
185 matcher_id => $matcher_id,
186 code => $matcher->code(),
187 description => $matcher->description(),
191 sub delete_matching_rule {
192 my $template = shift;
193 my $matcher_id = shift;
195 my $matcher = C4::Matcher->fetch($matcher_id);
196 $template->param(deleted_matching_rule => $matcher->code(),
198 C4::Matcher->delete($matcher_id);
201 sub edit_matching_rule_form {
202 my $template = shift;
203 my $matcher_id = shift;
205 my $matcher = C4::Matcher->fetch($matcher_id);
207 $template->{VARS}->{'matcher_id'} = $matcher_id;
208 $template->{VARS}->{'code'} = $matcher->code();
209 $template->{VARS}->{'description'} = $matcher->description();
210 $template->{VARS}->{'threshold'} = $matcher->threshold();
211 $template->{VARS}->{'record_type'} = $matcher->record_type();
213 my $matcher_info = $matcher->dump();
214 my @matchpoints = ();
215 my $mp_num = 0;
216 foreach my $matchpoint (@{ $matcher_info->{'matchpoints'} }) {
217 $mp_num++;
218 my @components = _parse_components($matchpoint->{'components'});
219 push @matchpoints, {
220 mp_num => $mp_num,
221 index => $matchpoint->{'index'},
222 score => $matchpoint->{'score'},
223 components => \@components
226 $template->param(matchpoints => \@matchpoints);
228 my $mc_num = 0;
229 my @matchchecks = ();
230 foreach my $matchcheck (@{ $matcher_info->{'matchchecks'} }) {
231 $mc_num++;
232 my @src_components = _parse_components($matchcheck->{'source_matchpoint'}->{'components'});
233 my @tgt_components = _parse_components($matchcheck->{'target_matchpoint'}->{'components'});
234 push @matchchecks, {
235 mc_num => $mc_num,
236 src_components => \@src_components,
237 tgt_components => \@tgt_components
240 $template->param(matchchecks => \@matchchecks);
242 $template->param(
243 matching_rule_form => 1,
244 edit_matching_rule => 1,
245 confirm_op => 'edit_matching_rule_confirmed',
246 max_matchpoint => $mp_num,
247 max_matchcheck => $mc_num
252 sub _parse_components {
253 my $components_ref = shift;
254 my @components = ();
256 my $comp_num = 0;
257 foreach my $component (@{ $components_ref }) {
258 $comp_num++;
259 my $norm_num = 0;
260 my @norms;
261 foreach my $norm (@{ $component->{'norms'} }) {
262 $norm_num++;
263 push @norms, { norm_num => $norm_num, norm => $norm };
265 push @components, {
266 comp_num => $comp_num,
267 tag => $component->{'tag'},
268 subfields => join("", sort keys %{ $component->{'subfields'} }),
269 offset => $component->{'offset'},
270 'length' => $component->{'length'},
271 norms => \@norms
275 return @components;
278 sub matching_rule_list {
279 my $template = shift;
281 my @matching_rules = C4::Matcher::GetMatcherList();
282 $template->param(available_matching_rules => \@matching_rules);
283 $template->param(display_list => 1);