Bug 5187: Show place of publication (MARC21, 260$c), XSLT
[koha.git] / admin / matching-rules.pl
blob63e5a3fbabf3548c5416dc81b14dc834ca0f7915
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 under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 use strict;
22 use warnings;
24 use CGI;
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 my $input = new CGI;
34 my $op = $input->param('op') || '';
37 my ($template, $loggedinuser, $cookie)
38 = get_template_and_user({template_name => "admin/matching-rules.tmpl",
39 query => $input,
40 type => "intranet",
41 authnotrequired => 0,
42 flagsrequired => {parameters => 1},
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;
96 # do parsing
97 my $matcher = C4::Matcher->new('biblio', 1000); # FIXME biblio only for now
98 $matcher->code($input->param('code'));
99 $matcher->description($input->param('description'));
100 $matcher->threshold($input->param('threshold'));
102 # matchpoints
103 my @mp_nums = sort map { /^mp_(\d+)_search_index/ ? int($1): () } $input->param;
104 foreach my $mp_num (@mp_nums) {
105 my $index = $input->param("mp_${mp_num}_search_index");
106 my $score = $input->param("mp_${mp_num}_score");
107 # components
108 my $components = [];
109 my @comp_nums = sort map { /^mp_${mp_num}_c_(\d+)_tag/ ? int($1): () } $input->param;
110 foreach my $comp_num (@comp_nums) {
111 my $component = {};
112 $component->{'tag'} = $input->param("mp_${mp_num}_c_${comp_num}_tag");
113 $component->{'subfields'} = $input->param("mp_${mp_num}_c_${comp_num}_subfields");
114 $component->{'offset'} = $input->param("mp_${mp_num}_c_${comp_num}_offset");
115 $component->{'length'} = $input->param("mp_${mp_num}_c_${comp_num}_length");
116 # norms
117 $component->{'norms'} = [];
118 my @norm_nums = sort map { /^mp_${mp_num}_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
119 foreach my $norm_num (@norm_nums) {
120 push @{ $component->{'norms'} }, $input->param("mp_${mp_num}_c_${comp_num}_n_${norm_num}_norm");
122 push @$components, $component;
124 $matcher->add_matchpoint($index, $score, $components);
127 # match checks
128 my @mc_nums = sort map { /^mc_(\d+)_id/ ? int($1): () } $input->param;
129 foreach my $mc_num (@mp_nums) {
130 # source components
131 my $src_components = [];
132 my @src_comp_nums = sort map { /^mc_${mc_num}_src_c_(\d+)_tag/ ? int($1): () } $input->param;
133 foreach my $comp_num (@src_comp_nums) {
134 my $component = {};
135 $component->{'tag'} = $input->param("mc_${mc_num}_src_c_${comp_num}_tag");
136 $component->{'subfields'} = $input->param("mc_${mc_num}_src_c_${comp_num}_subfields");
137 $component->{'offset'} = $input->param("mc_${mc_num}_src_c_${comp_num}_offset");
138 $component->{'length'} = $input->param("mc_${mc_num}_src_c_${comp_num}_length");
139 # norms
140 $component->{'norms'} = [];
141 my @norm_nums = sort map { /^mc_${mc_num}_src_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
142 foreach my $norm_num (@norm_nums) {
143 push @{ $component->{'norms'} }, $input->param("mc_${mc_num}_src_c_${comp_num}_n_${norm_num}_norm");
145 push @$src_components, $component;
147 # target components
148 my $tgt_components = [];
149 my @tgt_comp_nums = sort map { /^mc_${mc_num}_tgt_c_(\d+)_tag/ ? int($1): () } $input->param;
150 foreach my $comp_num (@tgt_comp_nums) {
151 my $component = {};
152 $component->{'tag'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_tag");
153 $component->{'subfields'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_subfields");
154 $component->{'offset'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_offset");
155 $component->{'length'} = $input->param("mc_${mc_num}_tgt_c_${comp_num}_length");
156 # norms
157 $component->{'norms'} = [];
158 my @norm_nums = sort map { /^mc_${mc_num}_tgt_c_${comp_num}_n_(\d+)_norm/ ? int($1): () } $input->param;
159 foreach my $norm_num (@norm_nums) {
160 push @{ $component->{'norms'} }, $input->param("mc_${mc_num}_tgt_c_${comp_num}_n_${norm_num}_norm");
162 push @$tgt_components, $component;
164 $matcher->add_required_check($src_components, $tgt_components);
167 if (defined $matcher_id and $matcher_id =~ /^\d+/) {
168 $matcher->_id($matcher_id);
169 $template->param(edited_matching_rule => $matcher->code());
170 } else {
171 $template->param(added_matching_rule => $matcher->code());
173 $matcher_id = $matcher->store();
176 sub delete_matching_rule_form {
177 my $template = shift;
178 my $matcher_id = shift;
180 my $matcher = C4::Matcher->fetch($matcher_id);
181 $template->param(
182 delete_matching_rule_form => 1,
183 confirm_op => "delete_matching_rule_confirmed",
184 matcher_id => $matcher_id,
185 code => $matcher->code(),
186 description => $matcher->description(),
190 sub delete_matching_rule {
191 my $template = shift;
192 my $matcher_id = shift;
194 my $matcher = C4::Matcher->fetch($matcher_id);
195 $template->param(deleted_matching_rule => $matcher->code(),
197 C4::Matcher->delete($matcher_id);
200 sub edit_matching_rule_form {
201 my $template = shift;
202 my $matcher_id = shift;
204 my $matcher = C4::Matcher->fetch($matcher_id);
206 $template->param(matcher_id => $matcher_id);
207 $template->param(code => $matcher->code());
208 $template->param(description => $matcher->description());
209 $template->param(threshold => $matcher->threshold());
211 my $matcher_info = $matcher->dump();
212 my @matchpoints = ();
213 my $mp_num = 0;
214 foreach my $matchpoint (@{ $matcher_info->{'matchpoints'} }) {
215 $mp_num++;
216 my @components = _parse_components($matchpoint->{'components'});
217 push @matchpoints, {
218 mp_num => $mp_num,
219 index => $matchpoint->{'index'},
220 score => $matchpoint->{'score'},
221 components => \@components
224 $template->param(matchpoints => \@matchpoints);
226 my $mc_num = 0;
227 my @matchchecks = ();
228 foreach my $matchcheck (@{ $matcher_info->{'matchchecks'} }) {
229 $mc_num++;
230 my @src_components = _parse_components($matchcheck->{'source_matchpoint'}->{'components'});
231 my @tgt_components = _parse_components($matchcheck->{'target_matchpoint'}->{'components'});
232 push @matchchecks, {
233 mc_num => $mc_num,
234 src_components => \@src_components,
235 tgt_components => \@tgt_components
238 $template->param(matchchecks => \@matchchecks);
240 $template->param(
241 matching_rule_form => 1,
242 edit_matching_rule => 1,
243 confirm_op => 'edit_matching_rule_confirmed',
244 max_matchpoint => $mp_num,
245 max_matchcheck => $mc_num
250 sub _parse_components {
251 my $components_ref = shift;
252 my @components = ();
254 my $comp_num = 0;
255 foreach my $component (@{ $components_ref }) {
256 $comp_num++;
257 my $norm_num = 0;
258 my @norms;
259 foreach my $norm (@{ $component->{'norms'} }) {
260 $norm_num++;
261 push @norms, { norm_num => $norm_num, norm => $norm };
263 push @components, {
264 comp_num => $comp_num,
265 tag => $component->{'tag'},
266 subfields => join("", sort keys %{ $component->{'subfields'} }),
267 offset => $component->{'offset'},
268 'length' => $component->{'length'},
269 norms => \@norms
273 return @components;
276 sub matching_rule_list {
277 my $template = shift;
279 my @matching_rules = C4::Matcher::GetMatcherList();
280 $template->param(available_matching_rules => \@matching_rules);
281 $template->param(display_list => 1);