View | Details | Raw Unified | Return to bug 21280
Collapse All | Expand All

(-)a/Koha/MarcEditor.pm (+630 lines)
Line 0 Link Here
1
package Koha::MarcEditor;
2
3
# Copyright 2000-2002 Katipo Communications
4
# Copyright 2004-2010 BibLibre
5
# Copyright 2019 University of Helsinki (The National Library Of Finland)
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it under the
10
# terms of the GNU General Public License as published by the Free Software
11
# Foundation; either version 3 of the License, or (at your option) any later
12
# version.
13
#
14
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License along
19
# with Koha; if not, write to the Free Software Foundation, Inc.,
20
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22
use Modern::Perl;
23
24
use Readonly;
25
26
use C4::ClassSource;
27
use C4::Context;
28
29
use Koha::DateUtils;
30
31
use base qw(Class::Accessor);
32
33
# Constants to refer to the standard editor types
34
Readonly our $EDITOR_BIBLIO    => 'biblio';
35
Readonly our $EDITOR_AUTHORITY => 'authority';
36
37
=head1 NAME
38
39
Koha::MarcEditor - Koha MARC Editor class
40
41
=head1 API
42
43
=head2 Class Methods
44
45
=cut
46
47
=head2 new
48
49
    my $editor = Koha::MarcEditor->new({
50
        type => $Koha::MarcEditor::EDITOR_BIBLIO,
51
        tags => $self->{tags},
52
        used_tags => $tagsUsedLib,
53
        mandatory_z3950 => $mandatory_z3950,
54
        hostitemnumber => $hostitemnumber
55
    });
56
57
Returns a new MarcEditor object.
58
59
=cut
60
61
sub new {
62
    my ($class, $params) = @_;
63
64
    my $self = $class->SUPER::new();
65
    $self->_init($params);
66
    return $self;
67
}
68
69
=head2 Instance Methods
70
71
=head3 build_tabs
72
73
    $editor->build_tabs($template, $record, $encoding);
74
75
Builds tab data in the template
76
77
=cut
78
79
sub build_tabs {
80
    my ( $self, $template, $record, $encoding ) = @_;
81
82
    # fill arrays
83
    my @loop_data = ();
84
    my $tag;
85
86
    # in this array, we will push all the 10 tabs
87
    # to avoid having 10 tabs in the template : they will all be in the same BIG_LOOP
88
    my @BIG_LOOP;
89
    my %seen;
90
    my @tab_data; # all tags to display
91
    my $max_num_tab=-1;
92
93
    if (defined $self->{used_tags}) {
94
        foreach my $used ( @{$self->{used_tags}} ) {
95
            push @tab_data,$used->{tagfield} if not $seen{$used->{tagfield}};
96
            $seen{$used->{tagfield}}++;
97
        }
98
99
        foreach (@{$self->{used_tags}}) {
100
            if($_->{tab} > -1 && $_->{tab} >= $max_num_tab && $_->{tagfield} ne '995'){ # FIXME : MARC21 ?
101
                $max_num_tab = $_->{tab};
102
            }
103
        }
104
        if ($max_num_tab >= 9) {
105
            $max_num_tab = 9;
106
        }
107
    } else {
108
        foreach my $used ( keys %{$self->{tags}} ) {
109
            push @tab_data,$used if not $seen{$used};
110
            $seen{$used}++;
111
        }
112
        @tab_data = sort @tab_data;
113
        $max_num_tab = 9;
114
    }
115
116
    # loop through each tab 0 through 9
117
    for ( my $tabloop = 0 ; $tabloop <= $max_num_tab ; $tabloop++ ) {
118
        my @loop_data = (); #innerloop in the template.
119
        my $i = 0;
120
        foreach my $tag (@tab_data) {
121
            $i++;
122
            next if ! $tag;
123
            my ($indicator1, $indicator2);
124
            my $index_tag = $self->_create_key();
125
126
            # if MARC::Record is not empty =>use it as master loop, then add missing subfields that should be in the tab.
127
            # if MARC::Record is empty => use tab as master loop.
128
            if ( $record ne -1 && ( $record->field($tag) || $tag eq '000' ) ) {
129
                my @fields;
130
                if ( $tag ne '000' ) {
131
                    @fields = $record->field($tag);
132
                }
133
                else {
134
                    push @fields, $record->leader(); # if tag == 000
135
                }
136
                # loop through each field
137
                foreach my $field (@fields) {
138
139
                    my @subfields_data;
140
                    if ( $tag < 10 ) {
141
                        my ( $value, $subfield );
142
                        if ( $tag ne '000' ) {
143
                            $value    = $field->data();
144
                            $subfield = "@";
145
                        }
146
                        else {
147
                            $value    = $field;
148
                            $subfield = '@';
149
                        }
150
                        next if ( $self->{tags}->{$tag}->{$subfield}->{tab} ne $tabloop );
151
                        next if $self->{tags}->{$tag}->{$subfield}->{hidden} && $subfield ne '9'
152
                            && $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY;
153
                        next
154
                          if ( $self->{tags}->{$tag}->{$subfield}->{kohafield} eq
155
                            'biblio.biblionumber' );
156
                        push(
157
                            @subfields_data,
158
                            $self->_create_input(
159
                                $tag, $subfield, $value, $index_tag, $tabloop, $record,
160
                            )
161
                        );
162
                    }
163
                    else {
164
                        my @subfields = $field->subfields();
165
                        foreach my $subfieldcount ( 0 .. $#subfields ) {
166
                            my $subfield = $subfields[$subfieldcount][0];
167
                            my $value    = $subfields[$subfieldcount][1];
168
                            next if ( length $subfield != 1 );
169
                            next if ( $self->{tags}->{$tag}->{$subfield}->{tab} ne $tabloop );
170
                            next if $self->{tags}->{$tag}->{$subfield}->{hidden} && $subfield ne '9'
171
                                && $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY;
172
                            push(
173
                                @subfields_data,
174
                                $self->_create_input(
175
                                    $tag, $subfield, $value, $index_tag, $tabloop,
176
                                    $record
177
                                )
178
                            );
179
                        }
180
                    }
181
182
                    # now, loop again to add parameter subfield that are not in the MARC::Record
183
                    foreach my $subfield ( sort( keys %{ $self->{tags}->{$tag} } ) ) {
184
                        next if ( length $subfield != 1 );
185
                        next if ( $self->{tags}->{$tag}->{$subfield}->{tab} ne $tabloop );
186
                        next if ( $tag < 10 );
187
                        next if $self->{tags}->{$tag}->{$subfield}->{hidden} && $subfield ne '9'
188
                            && $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY;
189
                        next
190
                          if ( ( $self->{tags}->{$tag}->{$subfield}->{hidden} <= -4 )
191
                            or ( $self->{tags}->{$tag}->{$subfield}->{hidden} >= 5 ) )
192
                            and $self->{type} ne $Koha::MarcEditor::EDITOR_AUTHORITY
193
                            and not ( $subfield eq "9" and
194
                                      exists($self->{tags}->{$tag}->{'a'}->{authtypecode}) and
195
                                      defined($self->{tags}->{$tag}->{'a'}->{authtypecode}) and
196
                                      $self->{tags}->{$tag}->{'a'}->{authtypecode} ne ""
197
                                    )
198
                          ;    #check for visibility flag
199
                               # if subfield is $9 in a field whose $a is authority-controlled,
200
                               # always include in the form regardless of the hidden setting - bug 2206
201
                        next if ( defined( $field->subfield($subfield) ) );
202
                        push(
203
                            @subfields_data,
204
                            $self->_create_input(
205
                                $tag, $subfield, '', $index_tag, $tabloop, $record
206
                            )
207
                        );
208
                    }
209
                    if ( $#subfields_data >= 0 ) {
210
                        # build the tag entry.
211
                        # note that the random() field is mandatory. Otherwise, on repeated fields, you'll
212
                        # have twice the same "name" value, and cgi->param() will return only one, making
213
                        # all subfields to be merged in a single field.
214
                        my %tag_data = (
215
                            tag           => $tag,
216
                            index         => $index_tag,
217
                            tag_lib       => $self->{tags}->{$tag}->{lib},
218
                            repeatable    => $self->{tags}->{$tag}->{repeatable},
219
                            mandatory     => $self->{tags}->{$tag}->{mandatory},
220
                            subfield_loop => \@subfields_data,
221
                            fixedfield    => $tag < 10 ? 1 : 0,
222
                            random        => $self->_create_key(),
223
                        );
224
                        if ($tag >= 10){ # no indicator for 00x tags
225
                           $tag_data{indicator1} = $self->_format_indicator($field->indicator(1)),
226
                           $tag_data{indicator2} = $self->_format_indicator($field->indicator(2)),
227
                        }
228
                        push( @loop_data, \%tag_data );
229
                    }
230
                 } # foreach $field end
231
232
            # if breeding is empty
233
            }
234
            else {
235
                my @subfields_data;
236
                foreach my $subfield ( sort( keys %{ $self->{tags}->{$tag} } ) ) {
237
                    next if ( length $subfield != 1 );
238
                    next if $self->{tags}->{$tag}->{$subfield}->{hidden} && $subfield ne '9'
239
                        && $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY;
240
                    next
241
                      if ( ( $self->{tags}->{$tag}->{$subfield}->{hidden} <= -4 )
242
                        or ( $self->{tags}->{$tag}->{$subfield}->{hidden} >= 5 ) )
243
                        and $self->{type} ne $Koha::MarcEditor::EDITOR_AUTHORITY
244
                        and not ( $subfield eq "9" and
245
                                exists($self->{tags}->{$tag}->{'a'}->{authtypecode}) and
246
                                defined($self->{tags}->{$tag}->{'a'}->{authtypecode}) and
247
                                $self->{tags}->{$tag}->{'a'}->{authtypecode} ne ""
248
                              )
249
                      ;    #check for visibility flag
250
                           # if subfield is $9 in a field whose $a is authority-controlled,
251
                           # always include in the form regardless of the hidden setting - bug 2206
252
                    next
253
                      if ( $self->{tags}->{$tag}->{$subfield}->{tab} ne $tabloop );
254
                    push(
255
                        @subfields_data,
256
                        $self->_create_input(
257
                            $tag, $subfield, '', $index_tag, $tabloop, $record
258
                        )
259
                    );
260
                }
261
                if ( $#subfields_data >= 0 ) {
262
                    my %tag_data = (
263
                        tag              => $tag,
264
                        index            => $index_tag,
265
                        tag_lib          => $self->{tags}->{$tag}->{lib},
266
                        repeatable       => $self->{tags}->{$tag}->{repeatable},
267
                        mandatory        => $self->{tags}->{$tag}->{mandatory},
268
                        indicator1       => ( $indicator1 || $self->{tags}->{$tag}->{ind1_defaultvalue} ), #if not set, try to load the default value
269
                        indicator2       => ( $indicator2 || $self->{tags}->{$tag}->{ind2_defaultvalue} ), #use short-circuit operator for efficiency
270
                        subfield_loop    => \@subfields_data,
271
                        tagfirstsubfield => $subfields_data[0],
272
                        fixedfield       => $tag < 10 ? 1 : 0,
273
                    );
274
275
                    push @loop_data, \%tag_data;
276
                }
277
            }
278
        }
279
        if ( $#loop_data >= 0 ) {
280
            push @BIG_LOOP, {
281
                number    => $tabloop,
282
                innerloop => \@loop_data,
283
            };
284
        }
285
    }
286
    $template->param( BIG_LOOP => \@BIG_LOOP );
287
}
288
289
=head2 Internal methods
290
291
=cut
292
293
=head3 _init
294
295
    $self->init(\%params);
296
297
Initialize settings
298
299
=cut
300
301
sub _init {
302
    my ($self, $params) = @_;
303
304
    $self->{type} = $params->{type};
305
    $self->{tags} = $params->{tags};
306
    $self->{used_tags} = $params->{used_tags};
307
    $self->{mandatory_z3950} = $params->{mandatory_z3950};
308
    $self->{hostitemnumber} = $params->{hostitemnumber} // '';
309
}
310
311
=head3 _build_authorized_values_list
312
313
    $subfield_data{marc_value} = $self->_build_authorized_values_list(
314
        $tag, $subfield, $value, $index_tag, $index_subfield
315
    );
316
317
Builds a list of authorized values
318
319
=cut
320
321
sub _build_authorized_values_list {
322
    my ( $self, $tag, $subfield, $value, $index_tag, $index_subfield ) = @_;
323
324
    my @authorised_values;
325
    my %authorised_lib;
326
327
    # builds list, depending on authorised value...
328
329
    #---- branch
330
    if ( $self->{tags}->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
331
        my $libraries = Koha::Libraries->search_filtered({}, {order_by => ['branchname']});
332
        while ( my $l = $libraries->next ) {
333
            push @authorised_values, $l->branchcode;;
334
            $authorised_lib{$l->branchcode} = $l->branchname;
335
        }
336
    }
337
    elsif ( $self->{tags}->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
338
        push @authorised_values, "";
339
340
        my $itemtype;
341
        my $itemtypes = Koha::ItemTypes->search_with_localization;
342
        while ( $itemtype = $itemtypes->next ) {
343
            push @authorised_values, $itemtype->itemtype;
344
            $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description;
345
        }
346
        $value = $itemtype unless ($value);
347
    }
348
    elsif ( $self->{tags}->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
349
        push @authorised_values, "";
350
351
        my $class_sources = GetClassSources();
352
353
        my $default_source = C4::Context->preference("DefaultClassificationSource");
354
355
        foreach my $class_source (sort keys %$class_sources) {
356
            next unless $class_sources->{$class_source}->{'used'} or
357
                        ($value and $class_source eq $value) or
358
                        ($class_source eq $default_source);
359
            push @authorised_values, $class_source;
360
            $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'};
361
        }
362
        $value = $default_source unless $value;
363
    }
364
    else {
365
        my $branch_limit = $self->{type} ne $Koha::MarcEditor::EDITOR_AUTHORITY && C4::Context->userenv
366
            ? C4::Context->userenv->{'branch'} : '';
367
368
        my $query;
369
        if ($branch_limit) {
370
            $query = "SELECT authorised_value, lib
371
                        FROM authorised_values";
372
            $query .= qq{ LEFT JOIN authorised_values_branches ON ( id = av_id )} if $branch_limit;
373
            $query .= " WHERE category = ?";
374
            $query .= " AND ( branchcode = ? OR branchcode IS NULL )" if $branch_limit;
375
            $query .= " GROUP BY lib ORDER BY lib, lib_opac";
376
        } else {
377
            $query = "SELECT authorised_value,lib
378
                FROM authorised_values
379
                WHERE category=? ORDER BY lib";
380
        }
381
        my $authorised_values_sth = C4::Context->dbh->prepare( $query );
382
383
        $authorised_values_sth->execute(
384
            $self->{tags}->{$tag}->{$subfield}->{authorised_value},
385
            $branch_limit ? $branch_limit : (),
386
        );
387
388
        push @authorised_values, "";
389
390
        while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
391
            push @authorised_values, $value;
392
            $authorised_lib{$value} = $lib;
393
        }
394
        $authorised_values_sth->finish;
395
    }
396
    return {
397
        type     => 'select',
398
        id       => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
399
        name     => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
400
        default  => $value,
401
        values   => \@authorised_values,
402
        labels   => \%authorised_lib,
403
    };
404
}
405
406
=head3 _create_input
407
408
 builds the <input ...> entry for a subfield.
409
410
=cut
411
412
sub _create_input {
413
    my ( $self, $tag, $subfield, $value, $index_tag, $tabloop, $rec ) = @_;
414
415
    my $index_subfield = $self->_create_key(); # create a specific key for each subfield
416
    my $tagdef = $self->{tags}->{$tag};
417
418
    # if there is no value provided but a default value in parameters, get it
419
    if ( $value eq '' ) {
420
        $value = $tagdef->{$subfield}->{defaultvalue} // q{};
421
422
        # get today date & replace <<YYYY>>, <<MM>>, <<DD>> if provided in the default value
423
        my $today_dt = dt_from_string;
424
        my $year = $today_dt->strftime('%Y');
425
        my $month = $today_dt->strftime('%m');
426
        my $day = $today_dt->strftime('%d');
427
        $value =~ s/<<YYYY>>/$year/g;
428
        $value =~ s/<<MM>>/$month/g;
429
        $value =~ s/<<DD>>/$day/g;
430
        # And <<USER>> with surname (?)
431
        my $username=(C4::Context->userenv?C4::Context->userenv->{'surname'}:"superlibrarian");
432
        $value=~s/<<USER>>/$username/g;
433
    }
434
435
    # map '@' as "subfield" label for fixed fields
436
    # to something that's allowed in a div id.
437
    my $id_subfield = $subfield;
438
    $id_subfield = "00" if $id_subfield eq "@";
439
440
    my %subfield_data = (
441
        tag        => $tag,
442
        subfield   => $id_subfield,
443
        marc_lib       => $tagdef->{$subfield}->{lib},
444
        tag_mandatory  => $tagdef->{mandatory},
445
        mandatory      => $tagdef->{$subfield}->{mandatory},
446
        repeatable     => $tagdef->{$subfield}->{repeatable},
447
        kohafield      => $tagdef->{$subfield}->{kohafield},
448
        index          => $index_tag,
449
        id             => "tag_".$tag."_subfield_".$id_subfield."_".$index_tag."_".$index_subfield,
450
        value          => $value,
451
        maxlength      => $tagdef->{$subfield}->{maxlength},
452
        random         => $self->_create_key(),
453
    );
454
455
    if(exists $self->{mandatory_z3950}->{$tag.$subfield}){
456
        $subfield_data{z3950_mandatory} = $self->{mandatory_z3950}->{$tag.$subfield};
457
    }
458
459
    if ($self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY) {
460
        # Authority subfield is hidden unless mandatory or contains something.
461
        $subfield_data{visibility} = "display:none;"
462
            if( $tagdef->{$subfield}->{hidden} and $value ne ''
463
                or ($value eq '' and !$tagdef->{$subfield}->{mandatory})
464
            );
465
    } else {
466
        # Subfield is hidden depending of hidden and mandatory flag, and is always
467
        # shown if it contains anything or if its field is mandatory.
468
        $subfield_data{visibility} = "display:none;"
469
            if $tagdef->{$subfield}->{hidden} % 2 == 1 &&
470
            $value eq '' &&
471
            !$tagdef->{$subfield}->{mandatory} &&
472
            !$tagdef->{mandatory};
473
474
        # expand all subfields of 773 if there is a host item provided in the input
475
        $subfield_data{visibility} ="" if ($tag eq 773 and $self->{hostitemnumber});
476
    }
477
478
    # it's an authorised field
479
    if ( $tagdef->{$subfield}->{authorised_value} ) {
480
        $subfield_data{marc_value} =
481
          $self->_build_authorized_values_list( $tag, $subfield, $value, $index_tag, $index_subfield );
482
483
    # it's a subfield $9 linking to an authority record - see bug 2206
484
    }
485
    elsif ($self->{type} eq $Koha::MarcEditor::EDITOR_BIBLIO and
486
           $subfield eq "9" and
487
           exists($tagdef->{'a'}->{authtypecode}) and
488
           defined($tagdef->{'a'}->{authtypecode}) and
489
           $tagdef->{'a'}->{authtypecode} ne '') {
490
491
        $subfield_data{marc_value} = {
492
            type      => 'text',
493
            id        => $subfield_data{id},
494
            name      => $subfield_data{id},
495
            value     => $value,
496
            size      => 5,
497
            maxlength => $subfield_data{maxlength},
498
            readonly  => 1,
499
        };
500
501
    # it's a thesaurus / authority field
502
    }
503
    elsif ( $tagdef->{$subfield}->{authtypecode} ) {
504
        # when authorities auto-creation is allowed, do not set readonly
505
        my $is_readonly = $self->{type} eq $Koha::MarcEditor::EDITOR_BIBLIO && !C4::Context->preference("BiblioAddsAuthorities");
506
507
        $subfield_data{marc_value} = {
508
            type      => $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY ? 'text1' : 'text',
509
            id        => $subfield_data{id},
510
            name      => $subfield_data{id},
511
            value     => $value,
512
            size      => 67,
513
            maxlength => $subfield_data{maxlength},
514
            readonly  => $is_readonly,
515
            authtype  => $tagdef->{$subfield}->{authtypecode},
516
        };
517
518
    # it's a plugin field
519
    } elsif ( $tagdef->{$subfield}->{'value_builder'} ) {
520
        require Koha::FrameworkPlugin;
521
        my $plugin = Koha::FrameworkPlugin->new( {
522
            name => $tagdef->{$subfield}->{'value_builder'},
523
        });
524
        my $pars= { dbh => C4::Context->dbh, record => $rec, tagslib => $self->{tags},
525
            id => $subfield_data{id}, tabloop => $tabloop };
526
        $plugin->build( $pars );
527
        if( !$plugin->errstr ) {
528
            $subfield_data{marc_value} = {
529
                type           => $self->{type} eq $Koha::MarcEditor::EDITOR_AUTHORITY ? 'text2' : 'text_complex',
530
                id             => $subfield_data{id},
531
                name           => $subfield_data{id},
532
                value          => $value,
533
                size           => 67,
534
                maxlength      => $subfield_data{maxlength},
535
                javascript     => $plugin->javascript,
536
                noclick        => $plugin->noclick,
537
            };
538
        } else {
539
            warn $plugin->errstr;
540
            # supply default input form
541
            $subfield_data{marc_value} = {
542
                type      => 'text',
543
                id        => $subfield_data{id},
544
                name      => $subfield_data{id},
545
                value     => $value,
546
                size      => 67,
547
                maxlength => $subfield_data{maxlength},
548
                readonly  => 0,
549
            };
550
        }
551
552
    # it's an hidden field
553
    } elsif ( $tag eq '' ) {
554
        $subfield_data{marc_value} = {
555
            type      => 'hidden',
556
            id        => $subfield_data{id},
557
            name      => $subfield_data{id},
558
            value     => $value,
559
            size      => 67,
560
            maxlength => $subfield_data{maxlength},
561
        };
562
563
    }
564
    else {
565
        # it's a standard field
566
        if (
567
            length($value) > 100
568
            or
569
            ( C4::Context->preference("marcflavour") eq "UNIMARC" && $tag >= 300
570
                and $tag < 400 && $subfield eq 'a' )
571
            or (    $tag >= 500
572
                and $tag < 600
573
                && C4::Context->preference("marcflavour") eq "MARC21" )
574
          )
575
        {
576
            $subfield_data{marc_value} = {
577
                type      => 'textarea',
578
                id        => $subfield_data{id},
579
                name      => $subfield_data{id},
580
                value     => $value,
581
            };
582
583
        }
584
        else {
585
            $subfield_data{marc_value} = {
586
                type      => 'text',
587
                id        => $subfield_data{id},
588
                name      => $subfield_data{id},
589
                value     => $value,
590
                size      => 67,
591
                maxlength => $subfield_data{maxlength},
592
                readonly  => 0,
593
            };
594
595
        }
596
    }
597
    $subfield_data{'index_subfield'} = $index_subfield;
598
    return \%subfield_data;
599
}
600
601
602
=head3 _format_indicator
603
604
Translate indicator value for output form - specifically, map
605
indicator = ' ' to ''.  This is for the convenience of a cataloger
606
using a mouse to select an indicator input.
607
608
=cut
609
610
sub _format_indicator {
611
    my ($self, $ind_value) = @_;
612
    return '' if not defined $ind_value;
613
    return '' if $ind_value eq ' ';
614
    return $ind_value;
615
}
616
617
=head3 _create_key
618
619
    $key = $self->_create_key():
620
621
Creates a random value to set it into the input name
622
623
=cut
624
625
sub _create_key {
626
    return int(rand(1000000));
627
}
628
629
630
1;
(-)a/authorities/authorities.pl (-472 / +18 lines)
Lines 33-52 use MARC::File::XML; Link Here
33
use C4::Biblio;
33
use C4::Biblio;
34
use Koha::Authority::Types;
34
use Koha::Authority::Types;
35
use Koha::ItemTypes;
35
use Koha::ItemTypes;
36
use vars qw( $tagslib);
36
use Koha::MarcEditor;
37
use vars qw( $authorised_values_sth);
38
use vars qw( $is_a_modif );
37
use vars qw( $is_a_modif );
39
38
40
my $itemtype; # created here because it can be used in build_authorized_values_list sub
39
our($is_a_modif);
41
our($authorised_values_sth,$is_a_modif,$usedTagsLib,$mandatory_z3950);
42
40
43
=head1 FUNCTIONS
41
=head1 FUNCTIONS
44
42
45
=over
43
=head2 MARCfindbreeding_auth
46
44
47
=item build_authorized_values_list
45
    $record = MARCfindbreeding_auth($breedingid);
48
46
49
builds list, depending on authorised value...
47
Look up the import record repository for the record with
48
record with id $breedingid.  If found, returns the decoded
49
MARC::Record; otherwise, -1 is returned (FIXME).
50
Returns as second parameter the character encoding.
50
51
51
=cut
52
=cut
52
53
Lines 65-322 sub MARCfindbreeding_auth { Link Here
65
    }
66
    }
66
}
67
}
67
68
68
sub build_authorized_values_list {
69
=head2 GetMandatoryFieldZ3950
69
    my ( $tag, $subfield, $value, $dbh, $authorised_values_sth,$index_tag,$index_subfield ) = @_;
70
71
    my @authorised_values;
72
    my %authorised_lib;
73
74
75
    #---- branch
76
    if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
77
        my $sth =
78
        $dbh->prepare(
79
            "select branchcode,branchname from branches order by branchname");
80
        $sth->execute;
81
        push @authorised_values, ""
82
        unless ( $tagslib->{$tag}->{$subfield}->{mandatory} );
83
84
        while ( my ( $branchcode, $branchname ) = $sth->fetchrow_array ) {
85
            push @authorised_values, $branchcode;
86
            $authorised_lib{$branchcode} = $branchname;
87
        }
88
    }
89
    elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
90
        push @authorised_values, ""
91
          unless ( $tagslib->{$tag}->{$subfield}->{mandatory}
92
            && ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) );
93
94
        my $itemtype;
95
        my $itemtypes = Koha::ItemTypes->search_with_localization;
96
        while ( $itemtype = $itemtypes->next ) {
97
            push @authorised_values, $itemtype->itemtype;
98
            $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description;
99
        }
100
        $value = $itemtype unless ($value);
101
102
        #---- "true" authorised value
103
    }
104
    else {
105
        $authorised_values_sth->execute(
106
            $tagslib->{$tag}->{$subfield}->{authorised_value} );
107
108
        push @authorised_values, ""
109
          unless ( $tagslib->{$tag}->{$subfield}->{mandatory}
110
            && ( $value || $tagslib->{$tag}->{$subfield}->{defaultvalue} ) );
111
112
        while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
113
            push @authorised_values, $value;
114
            $authorised_lib{$value} = $lib;
115
        }
116
    }
117
    return {
118
        type     => 'select',
119
        id       => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
120
        name     => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
121
        values   => \@authorised_values,
122
        labels   => \%authorised_lib,
123
        default  => $value,
124
    };
125
}
126
127
128
=item create_input
129
130
builds the <input ...> entry for a subfield.
131
132
=cut
133
134
sub create_input {
135
    my ( $tag, $subfield, $value, $index_tag, $tabloop, $rec, $authorised_values_sth,$cgi ) = @_;
136
    
137
    my $index_subfield = CreateKey(); # create a specifique key for each subfield
138
139
    # determine maximum length; 9999 bytes per ISO 2709 except for leader and MARC21 008
140
    my $max_length = 9999;
141
    if ($tag eq '000') {
142
        $max_length = 24;
143
    } elsif ($tag eq '008' and C4::Context->preference('marcflavour') eq 'MARC21')  {
144
        $max_length = 40;
145
    }
146
147
    # if there is no value provided but a default value in parameters, get it
148
    if ($value eq '') {
149
        $value = $tagslib->{$tag}->{$subfield}->{defaultvalue};
150
        if (!defined $value) {
151
            $value = q{};
152
        }
153
154
        # get today date & replace YYYY, MM, DD if provided in the default value
155
        my ( $year, $month, $day ) = Today();
156
        $month = sprintf( "%02d", $month );
157
        $day   = sprintf( "%02d", $day );
158
        $value =~ s/YYYY/$year/g;
159
        $value =~ s/MM/$month/g;
160
        $value =~ s/DD/$day/g;
161
    }
162
    my $dbh = C4::Context->dbh;
163
164
    # map '@' as "subfield" label for fixed fields
165
    # to something that's allowed in a div id.
166
    my $id_subfield = $subfield;
167
    $id_subfield = "00" if $id_subfield eq "@";
168
169
    my %subfield_data = (
170
        tag        => $tag,
171
        subfield   => $id_subfield,
172
        marc_lib       => $tagslib->{$tag}->{$subfield}->{lib},
173
        tag_mandatory  => $tagslib->{$tag}->{mandatory},
174
        mandatory      => $tagslib->{$tag}->{$subfield}->{mandatory},
175
        repeatable     => $tagslib->{$tag}->{$subfield}->{repeatable},
176
        kohafield      => $tagslib->{$tag}->{$subfield}->{kohafield},
177
        index          => $index_tag,
178
        id             => "tag_".$tag."_subfield_".$id_subfield."_".$index_tag."_".$index_subfield,
179
        value          => $value,
180
        random         => CreateKey(),
181
    );
182
183
    if(exists $mandatory_z3950->{$tag.$subfield}){
184
        $subfield_data{z3950_mandatory} = $mandatory_z3950->{$tag.$subfield};
185
    }
186
    
187
    $subfield_data{visibility} = "display:none;"
188
        if( $tagslib->{$tag}->{$subfield}->{hidden} and $value ne ''
189
            or ($value eq '' and !$tagslib->{$tag}->{$subfield}->{mandatory})
190
        );
191
    
192
    # it's an authorised field
193
    if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
194
        $subfield_data{marc_value} =
195
        build_authorized_values_list( $tag, $subfield, $value, $dbh,
196
            $authorised_values_sth,$index_tag,$index_subfield );
197
198
    # it's a thesaurus / authority field
199
    }
200
    elsif ( $tagslib->{$tag}->{$subfield}->{authtypecode} ) {
201
        $subfield_data{marc_value} = {
202
            type         => 'text1',
203
            id           => $subfield_data{id},
204
            name         => $subfield_data{id},
205
            value        => $value,
206
            authtypecode => $tagslib->{$tag}->{$subfield}->{authtypecode},
207
        };
208
    }
209
    elsif ( $tagslib->{$tag}->{$subfield}->{'value_builder'} ) { # plugin
210
        require Koha::FrameworkPlugin;
211
        my $plugin = Koha::FrameworkPlugin->new({
212
            name => $tagslib->{$tag}->{$subfield}->{'value_builder'},
213
        });
214
        my $pars=  { dbh => $dbh, record => $rec, tagslib =>$tagslib,
215
            id => $subfield_data{id}, tabloop => $tabloop };
216
        $plugin->build( $pars );
217
        if( !$plugin->errstr ) {
218
            $subfield_data{marc_value} = {
219
                type       => 'text2',
220
                id        => $subfield_data{id},
221
                name      => $subfield_data{id},
222
                value     => $value,
223
                maxlength => $max_length,
224
                javascript => $plugin->javascript,
225
                noclick    => $plugin->noclick,
226
            };
227
        } else { # warn and supply default field
228
            warn $plugin->errstr;
229
            $subfield_data{marc_value} = {
230
                type      => 'text',
231
                id        => $subfield_data{id},
232
                name      => $subfield_data{id},
233
                value     => $value,
234
                maxlength => $max_length,
235
            };
236
        }
237
    }
238
    # it's an hidden field
239
    elsif ( $tag eq '' ) {
240
        $subfield_data{marc_value} = {
241
            type      => 'hidden',
242
            id        => $subfield_data{id},
243
            name      => $subfield_data{id},
244
            value     => $value,
245
            maxlength => $max_length,
246
        }
247
    }
248
    elsif ( $tagslib->{$tag}->{$subfield}->{'hidden'} ) {
249
        $subfield_data{marc_value} = {
250
            type => 'text',
251
            id        => $subfield_data{id},
252
            name      => $subfield_data{id},
253
            value     => $value,
254
            maxlength => $max_length,
255
        };
256
257
        # it's a standard field
258
    }
259
    else {
260
        if (
261
            length($value) > 100
262
            or
263
            ( C4::Context->preference("marcflavour") eq "UNIMARC" && $tag >= 300
264
                and $tag < 400 && $subfield eq 'a' )
265
            or (    $tag >= 600
266
                and $tag < 700
267
                && C4::Context->preference("marcflavour") eq "MARC21" )
268
        )
269
        {
270
            $subfield_data{marc_value} = {
271
                type => 'textarea',
272
                id        => $subfield_data{id},
273
                name      => $subfield_data{id},
274
                value     => $value,
275
                maxlength => $max_length,
276
            };
277
278
        }
279
        else {
280
            $subfield_data{marc_value} = {
281
                type => 'text',
282
                id        => $subfield_data{id},
283
                name      => $subfield_data{id},
284
                value     => $value,
285
                maxlength => $max_length,
286
            };
287
288
        }
289
    }
290
    $subfield_data{'index_subfield'} = $index_subfield;
291
    return \%subfield_data;
292
}
293
294
=item format_indicator
295
296
Translate indicator value for output form - specifically, map
297
indicator = ' ' to ''.  This is for the convenience of a cataloger
298
using a mouse to select an indicator input.
299
300
=cut
301
302
sub format_indicator {
303
    my $ind_value = shift;
304
    return '' if not defined $ind_value;
305
    return '' if $ind_value eq ' ';
306
    return $ind_value;
307
}
308
309
=item CreateKey
310
311
Create a random value to set it into the input name
312
313
=cut
314
315
sub CreateKey {
316
    return int(rand(1000000));
317
}
318
319
=item GetMandatoryFieldZ3950
320
70
321
    This function returns a hashref which contains all mandatory field
71
    This function returns a hashref which contains all mandatory field
322
    to search with z3950 server.
72
    to search with z3950 server.
Lines 342-553 sub GetMandatoryFieldZ3950 { Link Here
342
    }
92
    }
343
}
93
}
344
94
345
sub build_tabs {
346
    my ( $template, $record, $dbh, $encoding,$input ) = @_;
347
348
    # fill arrays
349
    my @loop_data = ();
350
    my $tag;
351
352
    my $authorised_values_sth = $dbh->prepare(
353
        "SELECT authorised_value,lib
354
        FROM authorised_values
355
        WHERE category=? ORDER BY lib"
356
    );
357
    
358
    # in this array, we will push all the 10 tabs
359
    # to avoid having 10 tabs in the template : they will all be in the same BIG_LOOP
360
    my @BIG_LOOP;
361
    my %seen;
362
    my @tab_data; # all tags to display
363
    
364
    foreach my $used ( keys %$tagslib ){
365
        push @tab_data,$used if not $seen{$used};
366
        $seen{$used}++;
367
    }
368
        
369
    my $max_num_tab=9;
370
    # loop through each tab 0 through 9
371
    for ( my $tabloop = 0 ; $tabloop <= $max_num_tab ; $tabloop++ ) {
372
        my @loop_data = (); #innerloop in the template.
373
        my $i = 0;
374
        foreach my $tag (sort @tab_data) {
375
            $i++;
376
            next if ! $tag;
377
            my ($indicator1, $indicator2);
378
            my $index_tag = CreateKey;
379
380
            # if MARC::Record is not empty =>use it as master loop, then add missing subfields that should be in the tab.
381
            # if MARC::Record is empty => use tab as master loop.
382
            if ( $record != -1 && ( $record->field($tag) || $tag eq '000' ) ) {
383
                my @fields;
384
                if ( $tag ne '000' ) {
385
                                @fields = $record->field($tag);
386
                }
387
                else {
388
                push @fields, $record->leader(); # if tag == 000
389
                }
390
                # loop through each field
391
                foreach my $field (@fields) {
392
                    
393
                    my @subfields_data;
394
                    if ( $tag < 10 ) {
395
                        my ( $value, $subfield );
396
                        if ( $tag ne '000' ) {
397
                            $value    = $field->data();
398
                            $subfield = "@";
399
                        }
400
                        else {
401
                            $value    = $field;
402
                            $subfield = '@';
403
                        }
404
                        next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
405
                        next if $tagslib->{$tag}->{$subfield}->{hidden} && $subfield ne '9';
406
                        push(
407
                            @subfields_data,
408
                            &create_input(
409
                                $tag, $subfield, $value, $index_tag, $tabloop, $record,
410
                                $authorised_values_sth,$input
411
                            )
412
                        );
413
                    }
414
                    else {
415
                        my @subfields = $field->subfields();
416
                        foreach my $subfieldcount ( 0 .. $#subfields ) {
417
                            my $subfield = $subfields[$subfieldcount][0];
418
                            my $value    = $subfields[$subfieldcount][1];
419
                            next if ( length $subfield != 1 );
420
                            next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
421
                            next if $tagslib->{$tag}->{$subfield}->{hidden} && $subfield ne '9';
422
                            push(
423
                                @subfields_data,
424
                                &create_input(
425
                                    $tag, $subfield, $value, $index_tag, $tabloop,
426
                                    $record, $authorised_values_sth,$input
427
                                )
428
                            );
429
                        }
430
                    }
431
432
                    # now, loop again to add parameter subfield that are not in the MARC::Record
433
                    foreach my $subfield ( sort( keys %{ $tagslib->{$tag} } ) )
434
                    {
435
                        next if ( length $subfield != 1 );
436
                        next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
437
                        next if ( $tag < 10 );
438
                        next if $tagslib->{$tag}->{$subfield}->{hidden} && $subfield ne '9';
439
                        next if ( defined( $field->subfield($subfield) ) );
440
                        push(
441
                            @subfields_data,
442
                            &create_input(
443
                                $tag, $subfield, '', $index_tag, $tabloop, $record,
444
                                $authorised_values_sth,$input
445
                            )
446
                        );
447
                    }
448
                    if ( $#subfields_data >= 0 ) {
449
                        # build the tag entry.
450
                        # note that the random() field is mandatory. Otherwise, on repeated fields, you'll 
451
                        # have twice the same "name" value, and cgi->param() will return only one, making
452
                        # all subfields to be merged in a single field.
453
                        my %tag_data = (
454
                            tag           => $tag,
455
                            index         => $index_tag,
456
                            tag_lib       => $tagslib->{$tag}->{lib},
457
                            repeatable       => $tagslib->{$tag}->{repeatable},
458
                            mandatory       => $tagslib->{$tag}->{mandatory},
459
                            subfield_loop => \@subfields_data,
460
                            fixedfield    => ($tag < 10)?(1):(0),
461
                            random        => CreateKey,
462
                        );
463
                        if ($tag >= 10){ # no indicator for theses tag
464
                            $tag_data{indicator1} = format_indicator($field->indicator(1)),
465
                            $tag_data{indicator2} = format_indicator($field->indicator(2)),
466
                        }
467
                        push( @loop_data, \%tag_data );
468
                    }
469
                } # foreach $field end
470
471
            # if breeding is empty
472
            }
473
            else {
474
                my @subfields_data;
475
                foreach my $subfield ( sort( keys %{ $tagslib->{$tag} } ) ) {
476
                    next if ( length $subfield != 1 );
477
                    next if $tagslib->{$tag}->{$subfield}->{hidden} && $subfield ne '9';
478
                    next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
479
                    push(
480
                        @subfields_data,
481
                        &create_input(
482
                            $tag, $subfield, '', $index_tag, $tabloop, $record,
483
                            $authorised_values_sth,$input
484
                        )
485
                    );
486
                }
487
                if ( $#subfields_data >= 0 ) {
488
                    my %tag_data = (
489
                        tag              => $tag,
490
                        index            => $index_tag,
491
                        tag_lib          => $tagslib->{$tag}->{lib},
492
                        repeatable       => $tagslib->{$tag}->{repeatable},
493
                        mandatory       => $tagslib->{$tag}->{mandatory},
494
                        indicator1       => $indicator1,
495
                        indicator2       => $indicator2,
496
                        subfield_loop    => \@subfields_data,
497
                        tagfirstsubfield => $subfields_data[0],
498
                        fixedfield       => ($tag < 10)?(1):(0)
499
                    );
500
                    
501
                    push @loop_data, \%tag_data ;
502
                }
503
            }
504
        }
505
        if ( $#loop_data >= 0 ) {
506
            push @BIG_LOOP, {
507
                number    => $tabloop,
508
                innerloop => \@loop_data,
509
            };
510
        }
511
    }
512
    $template->param( BIG_LOOP => \@BIG_LOOP );
513
}
514
515
516
sub build_hidden_data {
517
    # build hidden data =>
518
    # we store everything, even if we show only requested subfields.
519
520
    my @loop_data =();
521
    my $i=0;
522
    foreach my $tag (keys %{$tagslib}) {
523
        my $previous_tag = '';
524
525
        # loop through each subfield
526
        foreach my $subfield (keys %{$tagslib->{$tag}}) {
527
            next if ($subfield eq 'lib');
528
            next if ($subfield eq 'tab');
529
            next if ($subfield eq 'mandatory');
530
                next if ($subfield eq 'repeatable');
531
            next if ($tagslib->{$tag}->{$subfield}->{'tab'}  ne "-1");
532
            my %subfield_data;
533
            $subfield_data{marc_lib}=$tagslib->{$tag}->{$subfield}->{lib};
534
            $subfield_data{marc_mandatory}=$tagslib->{$tag}->{$subfield}->{mandatory};
535
            $subfield_data{marc_repeatable}=$tagslib->{$tag}->{$subfield}->{repeatable};
536
            $subfield_data{marc_value} = {
537
                type => 'hidden_simple',
538
                name => 'field_value[]',
539
            };
540
            push(@loop_data, \%subfield_data);
541
            $i++
542
        }
543
    }
544
}
545
546
=back
547
548
=cut
549
550
551
# ======================== 
95
# ======================== 
552
#          MAIN 
96
#          MAIN 
553
#=========================
97
#=========================
Lines 577-585 my ($template, $loggedinuser, $cookie) Link Here
577
                            });
121
                            });
578
$template->param(nonav   => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid,);
122
$template->param(nonav   => $nonav,index=>$myindex,authtypecode=>$authtypecode,breedingid=>$breedingid,);
579
123
580
$tagslib = GetTagsLabels(1,$authtypecode);
581
$mandatory_z3950 = GetMandatoryFieldZ3950($authtypecode);
582
583
my $record=-1;
124
my $record=-1;
584
my $encoding="";
125
my $encoding="";
585
if (($authid) && !($breedingid)){
126
if (($authid) && !($breedingid)){
Lines 589-594 if ($breedingid) { Link Here
589
    ( $record, $encoding ) = MARCfindbreeding_auth( $breedingid );
130
    ( $record, $encoding ) = MARCfindbreeding_auth( $breedingid );
590
}
131
}
591
132
133
134
my $editor = Koha::MarcEditor->new({
135
    type => $Koha::MarcEditor::EDITOR_AUTHORITY,
136
    tags => GetTagsLabels(1,$authtypecode),
137
    mandatory_z3950 => GetMandatoryFieldZ3950($authtypecode)
138
});
139
592
my ($oldauthnumtagfield,$oldauthnumtagsubfield);
140
my ($oldauthnumtagfield,$oldauthnumtagsubfield);
593
my ($oldauthtypetagfield,$oldauthtypetagsubfield);
141
my ($oldauthtypetagfield,$oldauthtypetagsubfield);
594
$is_a_modif=0;
142
$is_a_modif=0;
Lines 628-635 if ($op eq "add") { Link Here
628
        exit;
176
        exit;
629
    } else {
177
    } else {
630
    # it may be a duplicate, warn the user and do nothing
178
    # it may be a duplicate, warn the user and do nothing
631
        build_tabs($template, $record, $dbh, $encoding,$input);
179
        $editor->build_tabs($template, $record, $encoding);
632
        build_hidden_data;
633
        $template->param(authid =>$authid,
180
        $template->param(authid =>$authid,
634
                        duplicateauthid     => $duplicateauthid,
181
                        duplicateauthid     => $duplicateauthid,
635
                        duplicateauthvalue  => $duplicateauthvalue->{'authorized'}->[0]->{'heading'},
182
                        duplicateauthvalue  => $duplicateauthvalue->{'authorized'}->[0]->{'heading'},
Lines 649-656 if ($op eq "duplicate") Link Here
649
        {
196
        {
650
                $authid = "";
197
                $authid = "";
651
        }
198
        }
652
        build_tabs ($template, $record, $dbh,$encoding,$input);
199
        $editor->build_tabs ($template, $record, $encoding);
653
        build_hidden_data;
654
        $template->param(oldauthtypetagfield=>$oldauthtypetagfield, oldauthtypetagsubfield=>$oldauthtypetagsubfield,
200
        $template->param(oldauthtypetagfield=>$oldauthtypetagfield, oldauthtypetagsubfield=>$oldauthtypetagsubfield,
655
                        oldauthnumtagfield=>$oldauthnumtagfield, oldauthnumtagsubfield=>$oldauthnumtagsubfield,
201
                        oldauthnumtagfield=>$oldauthnumtagfield, oldauthnumtagsubfield=>$oldauthnumtagsubfield,
656
                        authid                      => $authid , authtypecode=>$authtypecode,	);
202
                        authid                      => $authid , authtypecode=>$authtypecode,	);
(-)a/cataloguing/addbiblio.pl (-502 / +11 lines)
Lines 31-41 use C4::Context; Link Here
31
use MARC::Record;
31
use MARC::Record;
32
use C4::Log;
32
use C4::Log;
33
use C4::Koha;
33
use C4::Koha;
34
use C4::ClassSource;
35
use C4::ImportBatch;
34
use C4::ImportBatch;
36
use C4::Charset;
35
use C4::Charset;
37
use Koha::BiblioFrameworks;
36
use Koha::BiblioFrameworks;
38
use Koha::DateUtils;
37
use Koha::MarcEditor;
39
38
40
use Koha::ItemTypes;
39
use Koha::ItemTypes;
41
use Koha::Libraries;
40
use Koha::Libraries;
Lines 51-57 if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) { Link Here
51
    MARC::File::XML->default_record_format('UNIMARC');
50
    MARC::File::XML->default_record_format('UNIMARC');
52
}
51
}
53
52
54
our($tagslib,$authorised_values_sth,$is_a_modif,$usedTagsLib,$mandatory_z3950);
53
our($is_a_modif);
55
54
56
=head1 FUNCTIONS
55
=head1 FUNCTIONS
57
56
Lines 157-245 sub MARCfindbreeding { Link Here
157
    return -1;
156
    return -1;
158
}
157
}
159
158
160
=head2 build_authorized_values_list
161
162
=cut
163
164
sub build_authorized_values_list {
165
    my ( $tag, $subfield, $value, $dbh, $authorised_values_sth,$index_tag,$index_subfield ) = @_;
166
167
    my @authorised_values;
168
    my %authorised_lib;
169
170
    # builds list, depending on authorised value...
171
172
    #---- branch
173
    if ( $tagslib->{$tag}->{$subfield}->{'authorised_value'} eq "branches" ) {
174
        my $libraries = Koha::Libraries->search_filtered({}, {order_by => ['branchname']});
175
        while ( my $l = $libraries->next ) {
176
            push @authorised_values, $l->branchcode;;
177
            $authorised_lib{$l->branchcode} = $l->branchname;
178
        }
179
    }
180
    elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "itemtypes" ) {
181
        push @authorised_values, "";
182
183
        my $itemtype;
184
        my $itemtypes = Koha::ItemTypes->search_with_localization;
185
        while ( $itemtype = $itemtypes->next ) {
186
            push @authorised_values, $itemtype->itemtype;
187
            $authorised_lib{$itemtype->itemtype} = $itemtype->translated_description;
188
        }
189
        $value = $itemtype unless ($value);
190
    }
191
    elsif ( $tagslib->{$tag}->{$subfield}->{authorised_value} eq "cn_source" ) {
192
        push @authorised_values, "";
193
194
        my $class_sources = GetClassSources();
195
196
        my $default_source = C4::Context->preference("DefaultClassificationSource");
197
198
        foreach my $class_source (sort keys %$class_sources) {
199
            next unless $class_sources->{$class_source}->{'used'} or
200
                        ($value and $class_source eq $value) or
201
                        ($class_source eq $default_source);
202
            push @authorised_values, $class_source;
203
            $authorised_lib{$class_source} = $class_sources->{$class_source}->{'description'};
204
        }
205
        $value = $default_source unless $value;
206
    }
207
    else {
208
        my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : "";
209
        $authorised_values_sth->execute(
210
            $tagslib->{$tag}->{$subfield}->{authorised_value},
211
            $branch_limit ? $branch_limit : (),
212
        );
213
214
        push @authorised_values, "";
215
216
        while ( my ( $value, $lib ) = $authorised_values_sth->fetchrow_array ) {
217
            push @authorised_values, $value;
218
            $authorised_lib{$value} = $lib;
219
        }
220
    }
221
    $authorised_values_sth->finish;
222
    return {
223
        type     => 'select',
224
        id       => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
225
        name     => "tag_".$tag."_subfield_".$subfield."_".$index_tag."_".$index_subfield,
226
        default  => $value,
227
        values   => \@authorised_values,
228
        labels   => \%authorised_lib,
229
    };
230
231
}
232
233
=head2 CreateKey
234
235
    Create a random value to set it into the input name
236
237
=cut
238
239
sub CreateKey {
240
    return int(rand(1000000));
241
}
242
243
=head2 GetMandatoryFieldZ3950
159
=head2 GetMandatoryFieldZ3950
244
160
245
    This function returns a hashref which contains all mandatory field
161
    This function returns a hashref which contains all mandatory field
Lines 264-677 sub GetMandatoryFieldZ3950 { Link Here
264
    };
180
    };
265
}
181
}
266
182
267
=head2 create_input
268
269
 builds the <input ...> entry for a subfield.
270
271
=cut
272
273
sub create_input {
274
    my ( $tag, $subfield, $value, $index_tag, $tabloop, $rec, $authorised_values_sth,$cgi ) = @_;
275
    
276
    my $index_subfield = CreateKey(); # create a specifique key for each subfield
277
278
    # if there is no value provided but a default value in parameters, get it
279
    if ( $value eq '' ) {
280
        $value = $tagslib->{$tag}->{$subfield}->{defaultvalue} // q{};
281
282
        # get today date & replace <<YYYY>>, <<MM>>, <<DD>> if provided in the default value
283
        my $today_dt = dt_from_string;
284
        my $year = $today_dt->strftime('%Y');
285
        my $month = $today_dt->strftime('%m');
286
        my $day = $today_dt->strftime('%d');
287
        $value =~ s/<<YYYY>>/$year/g;
288
        $value =~ s/<<MM>>/$month/g;
289
        $value =~ s/<<DD>>/$day/g;
290
        # And <<USER>> with surname (?)
291
        my $username=(C4::Context->userenv?C4::Context->userenv->{'surname'}:"superlibrarian");
292
        $value=~s/<<USER>>/$username/g;
293
    
294
    }
295
    my $dbh = C4::Context->dbh;
296
297
    # map '@' as "subfield" label for fixed fields
298
    # to something that's allowed in a div id.
299
    my $id_subfield = $subfield;
300
    $id_subfield = "00" if $id_subfield eq "@";
301
302
    my %subfield_data = (
303
        tag        => $tag,
304
        subfield   => $id_subfield,
305
        marc_lib       => $tagslib->{$tag}->{$subfield}->{lib},
306
        tag_mandatory  => $tagslib->{$tag}->{mandatory},
307
        mandatory      => $tagslib->{$tag}->{$subfield}->{mandatory},
308
        repeatable     => $tagslib->{$tag}->{$subfield}->{repeatable},
309
        kohafield      => $tagslib->{$tag}->{$subfield}->{kohafield},
310
        index          => $index_tag,
311
        id             => "tag_".$tag."_subfield_".$id_subfield."_".$index_tag."_".$index_subfield,
312
        value          => $value,
313
        maxlength      => $tagslib->{$tag}->{$subfield}->{maxlength},
314
        random         => CreateKey(),
315
    );
316
317
    if(exists $mandatory_z3950->{$tag.$subfield}){
318
        $subfield_data{z3950_mandatory} = $mandatory_z3950->{$tag.$subfield};
319
    }
320
    # Subfield is hidden depending of hidden and mandatory flag, and is always
321
    # shown if it contains anything or if its field is mandatory.
322
    my $tdef = $tagslib->{$tag};
323
    $subfield_data{visibility} = "display:none;"
324
        if $tdef->{$subfield}->{hidden} % 2 == 1 &&
325
           $value eq '' &&
326
           !$tdef->{$subfield}->{mandatory} &&
327
           !$tdef->{mandatory};
328
    # expand all subfields of 773 if there is a host item provided in the input
329
    $subfield_data{visibility} ="" if ($tag eq 773 and $cgi->param('hostitemnumber'));
330
331
332
    # it's an authorised field
333
    if ( $tagslib->{$tag}->{$subfield}->{authorised_value} ) {
334
        $subfield_data{marc_value} =
335
          build_authorized_values_list( $tag, $subfield, $value, $dbh,
336
            $authorised_values_sth,$index_tag,$index_subfield );
337
338
    # it's a subfield $9 linking to an authority record - see bug 2206
339
    }
340
    elsif ($subfield eq "9" and
341
           exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
342
           defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
343
           $tagslib->{$tag}->{'a'}->{authtypecode} ne '') {
344
345
        $subfield_data{marc_value} = {
346
            type      => 'text',
347
            id        => $subfield_data{id},
348
            name      => $subfield_data{id},
349
            value     => $value,
350
            size      => 5,
351
            maxlength => $subfield_data{maxlength},
352
            readonly  => 1,
353
        };
354
355
    # it's a thesaurus / authority field
356
    }
357
    elsif ( $tagslib->{$tag}->{$subfield}->{authtypecode} ) {
358
        # when authorities auto-creation is allowed, do not set readonly
359
        my $is_readonly = !C4::Context->preference("BiblioAddsAuthorities");
360
361
        $subfield_data{marc_value} = {
362
            type      => 'text',
363
            id        => $subfield_data{id},
364
            name      => $subfield_data{id},
365
            value     => $value,
366
            size      => 67,
367
            maxlength => $subfield_data{maxlength},
368
            readonly  => ($is_readonly) ? 1 : 0,
369
            authtype  => $tagslib->{$tag}->{$subfield}->{authtypecode},
370
        };
371
372
    # it's a plugin field
373
    } elsif ( $tagslib->{$tag}->{$subfield}->{'value_builder'} ) {
374
        require Koha::FrameworkPlugin;
375
        my $plugin = Koha::FrameworkPlugin->new( {
376
            name => $tagslib->{$tag}->{$subfield}->{'value_builder'},
377
        });
378
        my $pars= { dbh => $dbh, record => $rec, tagslib => $tagslib,
379
            id => $subfield_data{id}, tabloop => $tabloop };
380
        $plugin->build( $pars );
381
        if( !$plugin->errstr ) {
382
            $subfield_data{marc_value} = {
383
                type           => 'text_complex',
384
                id             => $subfield_data{id},
385
                name           => $subfield_data{id},
386
                value          => $value,
387
                size           => 67,
388
                maxlength      => $subfield_data{maxlength},
389
                javascript     => $plugin->javascript,
390
                noclick        => $plugin->noclick,
391
            };
392
        } else {
393
            warn $plugin->errstr;
394
            # supply default input form
395
            $subfield_data{marc_value} = {
396
                type      => 'text',
397
                id        => $subfield_data{id},
398
                name      => $subfield_data{id},
399
                value     => $value,
400
                size      => 67,
401
                maxlength => $subfield_data{maxlength},
402
                readonly  => 0,
403
            };
404
        }
405
406
    # it's an hidden field
407
    } elsif ( $tag eq '' ) {
408
        $subfield_data{marc_value} = {
409
            type      => 'hidden',
410
            id        => $subfield_data{id},
411
            name      => $subfield_data{id},
412
            value     => $value,
413
            size      => 67,
414
            maxlength => $subfield_data{maxlength},
415
        };
416
417
    }
418
    else {
419
        # it's a standard field
420
        if (
421
            length($value) > 100
422
            or
423
            ( C4::Context->preference("marcflavour") eq "UNIMARC" && $tag >= 300
424
                and $tag < 400 && $subfield eq 'a' )
425
            or (    $tag >= 500
426
                and $tag < 600
427
                && C4::Context->preference("marcflavour") eq "MARC21" )
428
          )
429
        {
430
            $subfield_data{marc_value} = {
431
                type      => 'textarea',
432
                id        => $subfield_data{id},
433
                name      => $subfield_data{id},
434
                value     => $value,
435
            };
436
437
        }
438
        else {
439
            $subfield_data{marc_value} = {
440
                type      => 'text',
441
                id        => $subfield_data{id},
442
                name      => $subfield_data{id},
443
                value     => $value,
444
                size      => 67,
445
                maxlength => $subfield_data{maxlength},
446
                readonly  => 0,
447
            };
448
449
        }
450
    }
451
    $subfield_data{'index_subfield'} = $index_subfield;
452
    return \%subfield_data;
453
}
454
455
456
=head2 format_indicator
457
458
Translate indicator value for output form - specifically, map
459
indicator = ' ' to ''.  This is for the convenience of a cataloger
460
using a mouse to select an indicator input.
461
462
=cut
463
464
sub format_indicator {
465
    my $ind_value = shift;
466
    return '' if not defined $ind_value;
467
    return '' if $ind_value eq ' ';
468
    return $ind_value;
469
}
470
471
sub build_tabs {
472
    my ( $template, $record, $dbh, $encoding,$input ) = @_;
473
474
    # fill arrays
475
    my @loop_data = ();
476
    my $tag;
477
478
    my $branch_limit = C4::Context->userenv ? C4::Context->userenv->{"branch"} : "";
479
    my $query = "SELECT authorised_value, lib
480
                FROM authorised_values";
481
    $query .= qq{ LEFT JOIN authorised_values_branches ON ( id = av_id )} if $branch_limit;
482
    $query .= " WHERE category = ?";
483
    $query .= " AND ( branchcode = ? OR branchcode IS NULL )" if $branch_limit;
484
    $query .= " GROUP BY lib ORDER BY lib, lib_opac";
485
    my $authorised_values_sth = $dbh->prepare( $query );
486
487
    # in this array, we will push all the 10 tabs
488
    # to avoid having 10 tabs in the template : they will all be in the same BIG_LOOP
489
    my @BIG_LOOP;
490
    my %seen;
491
    my @tab_data; # all tags to display
492
    
493
    foreach my $used ( @$usedTagsLib ){
494
        push @tab_data,$used->{tagfield} if not $seen{$used->{tagfield}};
495
        $seen{$used->{tagfield}}++;
496
    }
497
        
498
    my $max_num_tab=-1;
499
    foreach(@$usedTagsLib){
500
        if($_->{tab} > -1 && $_->{tab} >= $max_num_tab && $_->{tagfield} != '995'){ # FIXME : MARC21 ?
501
            $max_num_tab = $_->{tab}; 
502
        }
503
    }
504
    if($max_num_tab >= 9){
505
        $max_num_tab = 9;
506
    }
507
    # loop through each tab 0 through 9
508
    for ( my $tabloop = 0 ; $tabloop <= $max_num_tab ; $tabloop++ ) {
509
        my @loop_data = (); #innerloop in the template.
510
        my $i = 0;
511
        foreach my $tag (@tab_data) {
512
            $i++;
513
            next if ! $tag;
514
            my ($indicator1, $indicator2);
515
            my $index_tag = CreateKey;
516
517
            # if MARC::Record is not empty =>use it as master loop, then add missing subfields that should be in the tab.
518
            # if MARC::Record is empty => use tab as master loop.
519
            if ( $record ne -1 && ( $record->field($tag) || $tag eq '000' ) ) {
520
                my @fields;
521
		if ( $tag ne '000' ) {
522
                    @fields = $record->field($tag);
523
		}
524
		else {
525
		   push @fields, $record->leader(); # if tag == 000
526
		}
527
		# loop through each field
528
                foreach my $field (@fields) {
529
                    
530
                    my @subfields_data;
531
                    if ( $tag < 10 ) {
532
                        my ( $value, $subfield );
533
                        if ( $tag ne '000' ) {
534
                            $value    = $field->data();
535
                            $subfield = "@";
536
                        }
537
                        else {
538
                            $value    = $field;
539
                            $subfield = '@';
540
                        }
541
                        next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
542
                        next
543
                          if ( $tagslib->{$tag}->{$subfield}->{kohafield} eq
544
                            'biblio.biblionumber' );
545
                        push(
546
                            @subfields_data,
547
                            &create_input(
548
                                $tag, $subfield, $value, $index_tag, $tabloop, $record,
549
                                $authorised_values_sth,$input
550
                            )
551
                        );
552
                    }
553
                    else {
554
                        my @subfields = $field->subfields();
555
                        foreach my $subfieldcount ( 0 .. $#subfields ) {
556
                            my $subfield = $subfields[$subfieldcount][0];
557
                            my $value    = $subfields[$subfieldcount][1];
558
                            next if ( length $subfield != 1 );
559
                            next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
560
                            push(
561
                                @subfields_data,
562
                                &create_input(
563
                                    $tag, $subfield, $value, $index_tag, $tabloop,
564
                                    $record, $authorised_values_sth,$input
565
                                )
566
                            );
567
                        }
568
                    }
569
570
                    # now, loop again to add parameter subfield that are not in the MARC::Record
571
                    foreach my $subfield ( sort( keys %{ $tagslib->{$tag} } ) )
572
                    {
573
                        next if ( length $subfield != 1 );
574
                        next if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
575
                        next if ( $tag < 10 );
576
                        next
577
                          if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 )
578
                            or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 ) )
579
                            and not ( $subfield eq "9" and
580
                                      exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
581
                                      defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
582
                                      $tagslib->{$tag}->{'a'}->{authtypecode} ne ""
583
                                    )
584
                          ;    #check for visibility flag
585
                               # if subfield is $9 in a field whose $a is authority-controlled,
586
                               # always include in the form regardless of the hidden setting - bug 2206
587
                        next if ( defined( $field->subfield($subfield) ) );
588
                        push(
589
                            @subfields_data,
590
                            &create_input(
591
                                $tag, $subfield, '', $index_tag, $tabloop, $record,
592
                                $authorised_values_sth,$input
593
                            )
594
                        );
595
                    }
596
                    if ( $#subfields_data >= 0 ) {
597
                        # build the tag entry.
598
                        # note that the random() field is mandatory. Otherwise, on repeated fields, you'll 
599
                        # have twice the same "name" value, and cgi->param() will return only one, making
600
                        # all subfields to be merged in a single field.
601
                        my %tag_data = (
602
                            tag           => $tag,
603
                            index         => $index_tag,
604
                            tag_lib       => $tagslib->{$tag}->{lib},
605
                            repeatable       => $tagslib->{$tag}->{repeatable},
606
                            mandatory       => $tagslib->{$tag}->{mandatory},
607
                            subfield_loop => \@subfields_data,
608
                            fixedfield    => $tag < 10?1:0,
609
                            random        => CreateKey,
610
                        );
611
                        if ($tag >= 10){ # no indicator for 00x tags
612
                           $tag_data{indicator1} = format_indicator($field->indicator(1)),
613
                           $tag_data{indicator2} = format_indicator($field->indicator(2)),
614
                        }
615
                        push( @loop_data, \%tag_data );
616
                    }
617
                 } # foreach $field end
618
619
            # if breeding is empty
620
            }
621
            else {
622
                my @subfields_data;
623
                foreach my $subfield ( sort( keys %{ $tagslib->{$tag} } ) ) {
624
                    next if ( length $subfield != 1 );
625
                    next
626
                      if ( ( $tagslib->{$tag}->{$subfield}->{hidden} <= -4 )
627
                        or ( $tagslib->{$tag}->{$subfield}->{hidden} >= 5 ) )
628
                      and not ( $subfield eq "9" and
629
                                exists($tagslib->{$tag}->{'a'}->{authtypecode}) and
630
                                defined($tagslib->{$tag}->{'a'}->{authtypecode}) and
631
                                $tagslib->{$tag}->{'a'}->{authtypecode} ne ""
632
                              )
633
                      ;    #check for visibility flag
634
                           # if subfield is $9 in a field whose $a is authority-controlled,
635
                           # always include in the form regardless of the hidden setting - bug 2206
636
                    next
637
                      if ( $tagslib->{$tag}->{$subfield}->{tab} ne $tabloop );
638
			push(
639
                        @subfields_data,
640
                        &create_input(
641
                            $tag, $subfield, '', $index_tag, $tabloop, $record,
642
                            $authorised_values_sth,$input
643
                        )
644
                    );
645
                }
646
                if ( $#subfields_data >= 0 ) {
647
                    my %tag_data = (
648
                        tag              => $tag,
649
                        index            => $index_tag,
650
                        tag_lib          => $tagslib->{$tag}->{lib},
651
                        repeatable       => $tagslib->{$tag}->{repeatable},
652
                        mandatory       => $tagslib->{$tag}->{mandatory},
653
                        indicator1       => ( $indicator1 || $tagslib->{$tag}->{ind1_defaultvalue} ), #if not set, try to load the default value
654
                        indicator2       => ( $indicator2 || $tagslib->{$tag}->{ind2_defaultvalue} ), #use short-circuit operator for efficiency
655
                        subfield_loop    => \@subfields_data,
656
                        tagfirstsubfield => $subfields_data[0],
657
                        fixedfield       => $tag < 10?1:0,
658
                    );
659
                    
660
                    push @loop_data, \%tag_data ;
661
                }
662
            }
663
        }
664
        if ( $#loop_data >= 0 ) {
665
            push @BIG_LOOP, {
666
                number    => $tabloop,
667
                innerloop => \@loop_data,
668
            };
669
        }
670
    }
671
    $authorised_values_sth->finish;
672
    $template->param( BIG_LOOP => \@BIG_LOOP );
673
}
674
675
# ========================
183
# ========================
676
#          MAIN
184
#          MAIN
677
#=========================
185
#=========================
Lines 748-758 $template->param( Link Here
748
    breedingid => $breedingid,
256
    breedingid => $breedingid,
749
);
257
);
750
258
751
# ++ Global
259
my $editor = Koha::MarcEditor->new({
752
$tagslib         = &GetMarcStructure( 1, $frameworkcode );
260
    type => $Koha::MarcEditor::EDITOR_BIBLIO,
753
$usedTagsLib     = &GetUsedMarcStructure( $frameworkcode );
261
    tags => GetMarcStructure( 1, $frameworkcode ),
754
$mandatory_z3950 = GetMandatoryFieldZ3950($frameworkcode);
262
    used_tags => GetUsedMarcStructure( $frameworkcode ),
755
# -- Global
263
    mandatory_z3950 => GetMandatoryFieldZ3950($frameworkcode),
264
    hostitemnumber => $hostitemnumber
265
});
756
266
757
my $record   = -1;
267
my $record   = -1;
758
my $encoding = "";
268
my $encoding = "";
Lines 894-900 if ( $op eq "addbiblio" ) { Link Here
894
        }
404
        }
895
    } else {
405
    } else {
896
    # it may be a duplicate, warn the user and do nothing
406
    # it may be a duplicate, warn the user and do nothing
897
        build_tabs ($template, $record, $dbh,$encoding,$input);
407
        $editor->build_tabs($template, $record, $encoding);
898
        $template->param(
408
        $template->param(
899
            biblionumber             => $biblionumber,
409
            biblionumber             => $biblionumber,
900
            biblioitemnumber         => $biblioitemnumber,
410
            biblioitemnumber         => $biblioitemnumber,
Lines 941-947 elsif ( $op eq "delete" ) { Link Here
941
            $record = $urecord;
451
            $record = $urecord;
942
        };
452
        };
943
    }
453
    }
944
    build_tabs( $template, $record, $dbh, $encoding,$input );
454
    $editor->build_tabs( $template, $record, $encoding );
945
    $template->param(
455
    $template->param(
946
        biblionumber             => $biblionumber,
456
        biblionumber             => $biblionumber,
947
        biblionumbertagfield        => $biblionumbertagfield,
457
        biblionumbertagfield        => $biblionumbertagfield,
948
- 

Return to bug 21280