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
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.
31 my $script_name = "/cgi-bin/koha/admin/matching-rules.pl";
34 my $op = $input->param('op') || '';
37 my ($template, $loggedinuser, $cookie)
38 = get_template_and_user
({template_name
=> "admin/matching-rules.tmpl",
42 flagsrequired
=> {parameters
=> 1},
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);
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);
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);
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);
73 matching_rule_list
($template);
76 output_html_with_http_headers
$input, $cookie, $template->output;
80 sub add_matching_rule_form
{
84 matching_rule_form
=> 1,
85 confirm_op
=> 'add_matching_rule_confirmed',
92 sub add_update_matching_rule
{
94 my $matcher_id = shift;
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'));
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");
109 my @comp_nums = sort map { /^mp_${mp_num}_c_(\d+)_tag/ ?
int($1): () } $input->param;
110 foreach my $comp_num (@comp_nums) {
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");
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);
128 my @mc_nums = sort map { /^mc_(\d+)_id/ ?
int($1): () } $input->param;
129 foreach my $mc_num (@mp_nums) {
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) {
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");
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;
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) {
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");
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());
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);
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 = ();
214 foreach my $matchpoint (@
{ $matcher_info->{'matchpoints'} }) {
216 my @components = _parse_components
($matchpoint->{'components'});
219 index => $matchpoint->{'index'},
220 score
=> $matchpoint->{'score'},
221 components
=> \
@components
224 $template->param(matchpoints
=> \
@matchpoints);
227 my @matchchecks = ();
228 foreach my $matchcheck (@
{ $matcher_info->{'matchchecks'} }) {
230 my @src_components = _parse_components
($matchcheck->{'source_matchpoint'}->{'components'});
231 my @tgt_components = _parse_components
($matchcheck->{'target_matchpoint'}->{'components'});
234 src_components
=> \
@src_components,
235 tgt_components
=> \
@tgt_components
238 $template->param(matchchecks
=> \
@matchchecks);
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;
255 foreach my $component (@
{ $components_ref }) {
259 foreach my $norm (@
{ $component->{'norms'} }) {
261 push @norms, { norm_num
=> $norm_num, norm
=> $norm };
264 comp_num
=> $comp_num,
265 tag
=> $component->{'tag'},
266 subfields
=> join("", sort keys %{ $component->{'subfields'} }),
267 offset
=> $component->{'offset'},
268 'length' => $component->{'length'},
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);