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

(-)a/C4/Biblio.pm (+45 lines)
Lines 105-110 BEGIN { Link Here
105
      &ModBiblioframework
105
      &ModBiblioframework
106
      &ModZebra
106
      &ModZebra
107
      &UpdateTotalIssues
107
      &UpdateTotalIssues
108
      &RemoveAllNsb
108
    );
109
    );
109
110
110
    # To delete something
111
    # To delete something
Lines 3876-3881 sub UpdateTotalIssues { Link Here
3876
     return;
3877
     return;
3877
}
3878
}
3878
3879
3880
=head2 RemoveAllNsb
3881
3882
    &RemoveAllNsb($record);
3883
3884
Removes all nsb/nse chars from a record
3885
3886
=cut
3887
3888
sub RemoveAllNsb {
3889
    my $record = shift;
3890
3891
    SetUTF8Flag($record);
3892
3893
    foreach my $field ($record->fields()) {
3894
        if ($field->is_control_field()) {
3895
            $field->update(nsb_clean($field->data()));
3896
        } else {
3897
            my @subfields = $field->subfields();
3898
            my @new_subfields;
3899
            foreach my $subfield (@subfields) {
3900
                push @new_subfields, $subfield->[0] => nsb_clean($subfield->[1]);
3901
            }
3902
            if (scalar(@new_subfields) > 0) {
3903
                my $new_field;
3904
                eval {
3905
                    $new_field = MARC::Field->new(
3906
                        $field->tag(),
3907
                        $field->indicator(1),
3908
                        $field->indicator(2),
3909
                        @new_subfields
3910
                    );
3911
                };
3912
                if ($@) {
3913
                    warn "error in RemoveAllNsb : $@";
3914
                } else {
3915
                    $field->replace_with($new_field);
3916
                }
3917
            }
3918
        }
3919
    }
3920
3921
    return $record;
3922
}
3923
3879
1;
3924
1;
3880
3925
3881
3926
(-)a/tools/export.pl (-119 / +237 lines)
Lines 26-70 use C4::AuthoritiesMarc; # GetAuthority Link Here
26
use CGI;
26
use CGI;
27
use C4::Koha;    # GetItemTypes
27
use C4::Koha;    # GetItemTypes
28
use C4::Branch;  # GetBranches
28
use C4::Branch;  # GetBranches
29
use C4::Record;
30
use Getopt::Long;
29
31
30
my $query = new CGI;
32
my $query = new CGI;
31
my $op=$query->param("op") || '';
33
32
my $filename=$query->param("filename");
34
my $commandline = 0;
33
my $dbh=C4::Context->dbh;
35
my $op;
36
my $filename;
37
my $dbh         = C4::Context->dbh;
34
my $marcflavour = C4::Context->preference("marcflavour");
38
my $marcflavour = C4::Context->preference("marcflavour");
39
my $clean;
40
my $output_format;
41
my $dont_export_items;
42
my $deleted_barcodes;
43
my $timestamp;
44
my $record_type;
45
my $help;
35
46
36
my ($template, $loggedinuser, $cookie)
47
# Checks if the script is called from commandline
37
    = get_template_and_user
48
if ( scalar @ARGV > 0 ) {
38
    (
49
39
        {
50
    # Getting parameters
40
            template_name => "tools/export.tmpl",
51
    $op = 'export';
41
            query => $query,
52
    GetOptions(
42
            type => "intranet",
53
        'format=s' => \$output_format,
43
            authnotrequired => 0,
54
        'date=s' => \$timestamp,
44
            flagsrequired => {tools => 'export_catalog'},
55
        'dont_export_items' => \$dont_export_items,
45
            debug => 1,
56
        'deleted_barcodes' => \$deleted_barcodes,
46
            }
57
        'clean' => \$clean,
58
        'filename=s' => \$filename,
59
        'record-type=s' => \$record_type,
60
        'help|?' => \$help
47
    );
61
    );
62
    $commandline = 1;
63
64
65
    if ($help) {
66
        print <<_USAGE_;
67
export.pl [--format=format] [--date=date] [--record-type=TYPE] [--dont_export_items] [--deleted_barcodes] [--clean] --filename=outputfile
68
69
70
 --format=FORMAT        FORMAT is either 'xml' or 'marc' (default)
71
72
 --date=DATE            DATE should be entered as the 'dateformat' syspref is
73
                        set (dd/mm/yyyy for metric, yyyy-mm-dd for iso,
74
                        mm/dd/yyyy for us) records exported are the ones that
75
                        have been modified since DATE
76
77
 --record-type=TYPE     TYPE is 'bibs' or 'auths'
78
79
 --deleted_barcodes     If used, a list of barcodes of items deleted since DATE
80
                        is produced (or from all deleted items if no date is
81
                        specified). Used only if TYPE is 'bibs'
82
83
 --clean                removes NSE/NSB
84
_USAGE_
85
        exit;
86
    }
87
88
    # Default parameters values :
89
    $output_format     ||= 'marc';
90
    $timestamp         ||= '';
91
    $dont_export_items ||= 0;
92
    $deleted_barcodes  ||= 0;
93
    $clean             ||= 0;
94
    $record_type       ||= "bibs";
48
95
49
	my $limit_ind_branch=(C4::Context->preference('IndependantBranches') &&
96
    # Redirect stdout
50
              C4::Context->userenv &&
97
    open STDOUT, ">$filename" if $filename;
51
              !(C4::Context->userenv->{flags} & 1) &&
98
52
              C4::Context->userenv->{branch}?1:0);
99
} else {
53
	my $branches = GetBranches($limit_ind_branch);    
100
54
    my $branch                = $query->param("branch") || '';
101
    $op          = $query->param("op") || '';
55
	if ( C4::Context->preference("IndependantBranches") &&
102
    $filename    = $query->param("filename") || 'koha.mrc';
56
         !(C4::Context->userenv->{flags} & 1) ) {
103
57
    	$branch = C4::Context->userenv->{'branch'};
104
}
58
	}
105
106
my ($template, $loggedinuser, $cookie) = get_template_and_user(
107
    {
108
        template_name => "tools/export.tmpl",
109
        query => $query,
110
        type => "intranet",
111
        authnotrequired => $commandline,
112
        flagsrequired => {tools => 'export_catalog'},
113
        debug => 1,
114
    }
115
);
116
117
my $limit_ind_branch = (
118
    C4::Context->preference('IndependantBranches') &&
119
    C4::Context->userenv &&
120
    !(C4::Context->userenv->{flags} & 1) &&
121
    C4::Context->userenv->{branch}
122
) ? 1 : 0;
123
124
my $branch = $query->param("branch") || '';
125
if ( C4::Context->preference("IndependantBranches") &&
126
     C4::Context->userenv &&
127
     !(C4::Context->userenv->{flags} & 1) ) {
128
    $branch = C4::Context->userenv->{'branch'};
129
}
59
130
60
if ($op eq "export") {
131
if ($op eq "export") {
61
    binmode STDOUT, ':encoding(UTF-8)';
132
    binmode STDOUT, ':encoding(UTF-8)';
62
	print $query->header(   -type => 'application/octet-stream', 
133
    print $query->header(
63
                            -charset => 'utf-8',
134
        -type => 'application/octet-stream',
64
                            -attachment=>$filename);
135
        -charset => 'utf-8',
136
        -attachment => $filename
137
    ) unless ($commandline);
65
     
138
     
66
    my $record_type        = $query->param("record_type");
139
    $record_type           = $query->param("record_type") unless ($commandline);
67
    my $output_format      = $query->param("output_format");
140
    $output_format         = $query->param("output_format") || 'marc' unless ($commandline);
68
    my $dont_export_fields = $query->param("dont_export_fields");
141
    my $dont_export_fields = $query->param("dont_export_fields");
69
    my @sql_params;
142
    my @sql_params;
70
    my $sql_query;
143
    my $sql_query;
Lines 74-79 if ($op eq "export") { Link Here
74
    my $itemtype             = $query->param("itemtype");
147
    my $itemtype             = $query->param("itemtype");
75
    my $start_callnumber     = $query->param("start_callnumber");
148
    my $start_callnumber     = $query->param("start_callnumber");
76
    my $end_callnumber       = $query->param("end_callnumber");
149
    my $end_callnumber       = $query->param("end_callnumber");
150
    $timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '' if ($commandline);
77
    my $start_accession =
151
    my $start_accession =
78
      ( $query->param("start_accession") )
152
      ( $query->param("start_accession") )
79
      ? C4::Dates->new( $query->param("start_accession") )
153
      ? C4::Dates->new( $query->param("start_accession") )
Lines 82-143 if ($op eq "export") { Link Here
82
      ( $query->param("end_accession") )
156
      ( $query->param("end_accession") )
83
      ? C4::Dates->new( $query->param("end_accession") )
157
      ? C4::Dates->new( $query->param("end_accession") )
84
      : '';
158
      : '';
85
    my $dont_export_items    = $query->param("dont_export_item");
159
    $dont_export_items    = $query->param("dont_export_item") unless ($commandline);
86
    my $strip_nonlocal_items = $query->param("strip_nonlocal_items");
160
    my $strip_nonlocal_items = $query->param("strip_nonlocal_items");
87
161
162
    my $biblioitemstable = ($commandline and $deleted_barcodes)
163
                                ? 'deletedbiblioitems'
164
                                : 'biblioitems';
165
    my $itemstable = ($commandline and $deleted_barcodes)
166
                                ? 'deleteditems'
167
                                : 'items';
168
88
    my $starting_authid = $query->param('starting_authid');
169
    my $starting_authid = $query->param('starting_authid');
89
    my $ending_authid   = $query->param('ending_authid');
170
    my $ending_authid   = $query->param('ending_authid');
90
    my $authtype        = $query->param('authtype');
171
    my $authtype        = $query->param('authtype');
91
172
92
    if ( $record_type eq 'bibs' ) {
173
    if ( $record_type eq 'bibs' ) {
93
        my $items_filter =
174
        if ($timestamp) {
94
            $branch || $start_callnumber || $end_callnumber ||
175
            # Specific query when timestamp is used
95
            $start_accession || $end_accession ||
176
            # Actually it's used only with CLI and so all previous filters
96
            ($itemtype && C4::Context->preference('item-level_itypes'));
177
            # are not used.
97
        $sql_query = $items_filter ?
178
            # If one day timestamp is used via the web interface, this part will
98
            "SELECT DISTINCT biblioitems.biblionumber
179
            # certainly have to be rewrited
99
            FROM biblioitems JOIN items
180
            $sql_query = " (
100
            USING (biblionumber) WHERE 1"
181
                SELECT biblionumber
101
            :
182
                FROM $biblioitemstable
102
            "SELECT biblioitems.biblionumber FROM biblioitems WHERE biblionumber >0 ";
183
                  LEFT JOIN items USING(biblionumber)
103
184
                WHERE $biblioitemstable.timestamp >= ?
104
        if ( $StartingBiblionumber ) {
185
                  OR items.timestamp >= ?
105
            $sql_query .= " AND biblioitems.biblionumber >= ? ";
186
            ) UNION (
106
            push @sql_params, $StartingBiblionumber;
187
                SELECT biblionumber
107
        }
188
                FROM $biblioitemstable
189
                  LEFT JOIN deleteditems USING(biblionumber)
190
                WHERE $biblioitemstable.timestamp >= ?
191
                  OR deleteditems.timestamp >= ?
192
            ) ";
193
            my $ts = $timestamp->output('iso');
194
            @sql_params = ($ts, $ts, $ts, $ts);
195
        } else {
196
            my $items_filter =
197
                $branch || $start_callnumber || $end_callnumber ||
198
                $start_accession || $timestamp || $end_accession ||
199
                ($itemtype && C4::Context->preference('item-level_itypes'));
200
            $sql_query = $items_filter ?
201
                "SELECT DISTINCT $biblioitemstable.biblionumber
202
                FROM $biblioitemstable JOIN $itemstable
203
                USING (biblionumber) WHERE 1"
204
                :
205
                "SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 ";
108
206
109
        if ( $EndingBiblionumber ) {
207
            if ( $StartingBiblionumber ) {
110
            $sql_query .= " AND biblioitems.biblionumber <= ? ";
208
                $sql_query .= " AND $biblioitemstable.biblionumber >= ? ";
111
            push @sql_params, $EndingBiblionumber;
209
                push @sql_params, $StartingBiblionumber;
112
        }
210
            }
113
211
114
        if ($branch) {
212
            if ( $EndingBiblionumber ) {
115
            $sql_query .= " AND homebranch = ? ";
213
                $sql_query .= " AND $biblioitemstable.biblionumber <= ? ";
116
            push @sql_params, $branch;
214
                push @sql_params, $EndingBiblionumber;
117
        }
215
            }
118
216
119
        if ($start_callnumber) {
217
            if ($branch) {
120
            $sql_query .= " AND itemcallnumber <= ? ";
218
                $sql_query .= " AND homebranch = ? ";
121
            push @sql_params, $start_callnumber;
219
                push @sql_params, $branch;
122
        }
220
            }
123
221
124
        if ($end_callnumber) {
222
            if ($start_callnumber) {
125
            $sql_query .= " AND itemcallnumber >= ? ";
223
                $sql_query .= " AND itemcallnumber <= ? ";
126
            push @sql_params, $end_callnumber;
224
                push @sql_params, $start_callnumber;
127
        }
225
            }
128
        if ($start_accession) {
129
            $sql_query .= " AND dateaccessioned >= ? ";
130
            push @sql_params, $start_accession->output('iso');
131
        }
132
226
133
        if ($end_accession) {
227
            if ($end_callnumber) {
134
            $sql_query .= " AND dateaccessioned <= ? ";
228
                $sql_query .= " AND itemcallnumber >= ? ";
135
            push @sql_params, $end_accession->output('iso');
229
                push @sql_params, $end_callnumber;
136
        }
230
            }
231
            if ($start_accession) {
232
                $sql_query .= " AND dateaccessioned >= ? ";
233
                push @sql_params, $start_accession->output('iso');
234
            }
235
236
            if ($end_accession) {
237
                $sql_query .= " AND dateaccessioned <= ? ";
238
                push @sql_params, $end_accession->output('iso');
239
            }
137
240
138
        if ( $itemtype ) {
241
            if ( $itemtype ) {
139
            $sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?";
242
                $sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?";
140
            push @sql_params, $itemtype;
243
                push @sql_params, $itemtype;
244
            }
141
        }
245
        }
142
    }
246
    }
143
    elsif ( $record_type eq 'auths' ) {
247
    elsif ( $record_type eq 'auths' ) {
Lines 164-224 if ($op eq "export") { Link Here
164
    $sth->execute(@sql_params);
268
    $sth->execute(@sql_params);
165
269
166
    while ( my ($recordid) = $sth->fetchrow ) {
270
    while ( my ($recordid) = $sth->fetchrow ) {
167
        my $record;
271
        if ( $deleted_barcodes ) {
168
        if ( $record_type eq 'bibs' ) {
272
            my $q = "
169
            $record = eval { GetMarcBiblio($recordid); };
273
                SELECT DISTINCT barcode
170
274
                FROM deleteditems
171
     # FIXME: decide how to handle records GetMarcBiblio can't parse or retrieve
275
                WHERE deleteditems.biblionumber = ?
172
            if ($@) {
276
            ";
173
                next;
277
            my $sth = $dbh->prepare($q);
278
            $sth->execute($recordid);
279
            while (my $row = $sth->fetchrow_array) {
280
                print "$row\n";
174
            }
281
            }
175
            next if not defined $record;
282
        } else {
176
            C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid )
283
            my $record;
177
              unless $dont_export_items;
284
            if ( $record_type eq 'bibs' ) {
178
            if ( $strip_nonlocal_items || $limit_ind_branch ) {
285
                $record = eval { GetMarcBiblio($recordid); };
179
                my ( $homebranchfield, $homebranchsubfield ) =
286
180
                  GetMarcFromKohaField( 'items.homebranch', '' );
287
                if ($@) {
181
                for my $itemfield ( $record->field($homebranchfield) ) {
288
                    next;
182
289
                }
183
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one
290
                next if not defined $record;
184
                    $branch = C4::Context->userenv->{'branch'} unless $branch;
291
                C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid )
185
                    $record->delete_field($itemfield)
292
                  unless $dont_export_items;
186
                      if (
293
                if ( $strip_nonlocal_items || $limit_ind_branch ) {
187
                        $itemfield->subfield($homebranchsubfield) ne $branch );
294
                    my ( $homebranchfield, $homebranchsubfield ) =
295
                      GetMarcFromKohaField( 'items.homebranch', '' );
296
                    for my $itemfield ( $record->field($homebranchfield) ) {
297
298
    # if stripping nonlocal items, use loggedinuser's branch if they didn't select one
299
                        $branch = C4::Context->userenv->{'branch'} unless $branch;
300
                        $record->delete_field($itemfield)
301
                          if (
302
                            $itemfield->subfield($homebranchsubfield) ne $branch );
303
                    }
188
                }
304
                }
189
            }
305
            }
190
        }
306
            elsif ( $record_type eq 'auths' ) {
191
        elsif ( $record_type eq 'auths' ) {
307
                $record = C4::AuthoritiesMarc::GetAuthority($recordid);
192
            $record = C4::AuthoritiesMarc::GetAuthority($recordid);
308
                next if not defined $record;
193
            next if not defined $record;
309
            }
194
        }
195
310
196
        if ( $dont_export_fields ) {
311
            if ( $dont_export_fields ) {
197
            my @fields = split " ", $dont_export_fields;
312
                my @fields = split " ", $dont_export_fields;
198
            foreach ( @fields ) {
313
                foreach ( @fields ) {
199
                /^(\d*)(\w)?$/;
314
                    /^(\d*)(\w)?$/;
200
                my $field = $1;
315
                    my $field = $1;
201
                my $subfield = $2;
316
                    my $subfield = $2;
202
                # skip if this record doesn't have this field
317
                    # skip if this record doesn't have this field
203
                next if not defined $record->field($field);
318
                    next if not defined $record->field($field);
204
                if( $subfield ) {
319
                    if( $subfield ) {
205
                    $record->field($field)->delete_subfields($subfield);
320
                        $record->field($field)->delete_subfields($subfield);
321
                    }
322
                    else {
323
                        $record->delete_field($record->field($field));
324
                    }
206
                }
325
                }
207
                else {
326
            }
208
                    $record->delete_field($record->field($field));
327
            RemoveAllNsb($record) if ($clean);
328
            if ( $output_format eq "xml" ) {
329
                if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') {
330
                    print $record->as_xml_record('UNIMARCAUTH');
331
                } else {
332
                    print $record->as_xml_record($marcflavour);
209
                }
333
                }
210
            }
334
            }
211
        }
335
            else {
212
        if ( $output_format eq "xml" ) {
336
                print $record->as_usmarc();
213
            if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') {
214
                print $record->as_xml_record('UNIMARCAUTH');
215
            } else {
216
                print $record->as_xml_record($marcflavour);
217
            }
337
            }
218
        }
338
        }
219
        else {
220
            print $record->as_usmarc();
221
        }
222
    }
339
    }
223
    exit;
340
    exit;
224
341
Lines 236-241 else { Link Here
236
            );
353
            );
237
       push @itemtypesloop, \%row;
354
       push @itemtypesloop, \%row;
238
    }
355
    }
356
    my $branches = GetBranches($limit_ind_branch);
239
    my @branchloop;
357
    my @branchloop;
240
    for my $thisbranch (
358
    for my $thisbranch (
241
        sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} }
359
        sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} }
Lines 264-269 else { Link Here
264
        itemtypeloop             => \@itemtypesloop,
382
        itemtypeloop             => \@itemtypesloop,
265
        DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
383
        DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(),
266
        authtypeloop             => \@authtypesloop,
384
        authtypeloop             => \@authtypesloop,
385
        dont_export_fields       => C4::Context->preference("DontExportFields"),
267
    );
386
    );
268
387
269
    output_html_with_http_headers $query, $cookie, $template->output;
388
    output_html_with_http_headers $query, $cookie, $template->output;
270
- 

Return to bug 5600