Lines 26-65
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 Data::Dumper; |
29 |
use C4::Record; |
|
|
30 |
use Getopt::Long; |
30 |
|
31 |
|
31 |
my $query = new CGI; |
32 |
my $query = new CGI; |
32 |
my $op=$query->param("op") || ''; |
|
|
33 |
my $filename=$query->param("filename"); |
34 |
$filename =~ s/(\r|\n)//; |
35 |
my $dbh=C4::Context->dbh; |
36 |
my $marcflavour = C4::Context->preference("marcflavour"); |
37 |
|
33 |
|
38 |
my ($template, $loggedinuser, $cookie, $flags) |
34 |
my $commandline = 0; |
39 |
= get_template_and_user |
35 |
my $op; |
40 |
( |
36 |
my $filename; |
41 |
{ |
37 |
my $dbh = C4::Context->dbh; |
42 |
template_name => "tools/export.tmpl", |
38 |
my $marcflavour = C4::Context->preference("marcflavour"); |
43 |
query => $query, |
39 |
my $clean; |
44 |
type => "intranet", |
40 |
my $output_format; |
45 |
authnotrequired => 0, |
41 |
my $dont_export_items; |
46 |
flagsrequired => {tools => 'export_catalog'}, |
42 |
my $deleted_barcodes; |
47 |
debug => 1, |
43 |
my $timestamp; |
48 |
} |
44 |
my $record_type; |
|
|
45 |
my $help; |
46 |
|
47 |
# Checks if the script is called from commandline |
48 |
if ( scalar @ARGV > 0 ) { |
49 |
|
50 |
# Getting parameters |
51 |
$op = 'export'; |
52 |
GetOptions( |
53 |
'format=s' => \$output_format, |
54 |
'date=s' => \$timestamp, |
55 |
'dont_export_items' => \$dont_export_items, |
56 |
'deleted_barcodes' => \$deleted_barcodes, |
57 |
'clean' => \$clean, |
58 |
'filename=s' => \$filename, |
59 |
'record-type=s' => \$record_type, |
60 |
'help|?' => \$help |
49 |
); |
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 |
|
50 |
|
69 |
|
51 |
my $limit_ind_branch=(C4::Context->preference('IndependantBranches') && |
70 |
--format=FORMAT FORMAT is either 'xml' or 'marc' (default) |
52 |
C4::Context->userenv && |
71 |
|
53 |
!(C4::Context->userenv->{flags} & 1) && |
72 |
--date=DATE DATE should be entered as the 'dateformat' syspref is |
54 |
C4::Context->userenv->{branch}?1:0); |
73 |
set (dd/mm/yyyy for metric, yyyy-mm-dd for iso, |
55 |
my $branches = GetBranches($limit_ind_branch); |
74 |
mm/dd/yyyy for us) records exported are the ones that |
56 |
my $branch = $query->param("branch") || ''; |
75 |
have been modified since DATE |
57 |
if ( C4::Context->preference("IndependantBranches") && |
76 |
|
58 |
!(C4::Context->userenv->{flags} & 1) ) { |
77 |
--record-type=TYPE TYPE is 'bibs' or 'auths' |
59 |
$branch = C4::Context->userenv->{'branch'}; |
78 |
|
60 |
} |
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"; |
95 |
|
96 |
# Redirect stdout |
97 |
open STDOUT, ">$filename" if $filename; |
98 |
|
99 |
} else { |
100 |
|
101 |
$op = $query->param("op") || ''; |
102 |
$filename = $query->param("filename") || 'koha.mrc'; |
103 |
$filename =~ s/(\r|\n)//; |
104 |
|
105 |
} |
106 |
|
107 |
my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( |
108 |
{ |
109 |
template_name => "tools/export.tmpl", |
110 |
query => $query, |
111 |
type => "intranet", |
112 |
authnotrequired => $commandline, |
113 |
flagsrequired => {tools => 'export_catalog'}, |
114 |
debug => 1, |
115 |
} |
116 |
); |
117 |
|
118 |
my $limit_ind_branch = ( |
119 |
C4::Context->preference('IndependantBranches') && |
120 |
C4::Context->userenv && |
121 |
!(C4::Context->userenv->{flags} & 1) && |
122 |
C4::Context->userenv->{branch} |
123 |
) ? 1 : 0; |
124 |
|
125 |
my $branch = $query->param("branch") || ''; |
126 |
if ( C4::Context->preference("IndependantBranches") && |
127 |
C4::Context->userenv && |
128 |
!(C4::Context->userenv->{flags} & 1) ) { |
129 |
$branch = C4::Context->userenv->{'branch'}; |
130 |
} |
61 |
|
131 |
|
62 |
my $backupdir = C4::Context->config('backupdir'); |
132 |
my $backupdir = C4::Context->config('backupdir'); |
|
|
133 |
warn $backupdir; |
63 |
|
134 |
|
64 |
if ($op eq "export") { |
135 |
if ($op eq "export") { |
65 |
my $charset = 'utf-8'; |
136 |
my $charset = 'utf-8'; |
Lines 74-85
if ($op eq "export") {
Link Here
|
74 |
binmode STDOUT; |
145 |
binmode STDOUT; |
75 |
$charset = ''; |
146 |
$charset = ''; |
76 |
} |
147 |
} |
77 |
print $query->header( -type => $mimetype, |
148 |
print $query->header( |
78 |
-charset => $charset, |
149 |
-type => $mimetype, |
79 |
-attachment=>$filename); |
150 |
-charset => $charset, |
80 |
|
151 |
-attachment => $filename |
81 |
my $record_type = $query->param("record_type"); |
152 |
) unless ($commandline); |
82 |
my $output_format = $query->param("output_format"); |
153 |
|
|
|
154 |
$record_type = $query->param("record_type") unless ($commandline); |
155 |
$output_format = $query->param("output_format") || 'marc' unless ($commandline); |
83 |
my $dont_export_fields = $query->param("dont_export_fields"); |
156 |
my $dont_export_fields = $query->param("dont_export_fields"); |
84 |
my @sql_params; |
157 |
my @sql_params; |
85 |
my $sql_query; |
158 |
my $sql_query; |
Lines 89-94
if ($op eq "export") {
Link Here
|
89 |
my $itemtype = $query->param("itemtype"); |
162 |
my $itemtype = $query->param("itemtype"); |
90 |
my $start_callnumber = $query->param("start_callnumber"); |
163 |
my $start_callnumber = $query->param("start_callnumber"); |
91 |
my $end_callnumber = $query->param("end_callnumber"); |
164 |
my $end_callnumber = $query->param("end_callnumber"); |
|
|
165 |
$timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '' if ($commandline); |
92 |
my $start_accession = |
166 |
my $start_accession = |
93 |
( $query->param("start_accession") ) |
167 |
( $query->param("start_accession") ) |
94 |
? C4::Dates->new( $query->param("start_accession") ) |
168 |
? C4::Dates->new( $query->param("start_accession") ) |
Lines 97-158
if ($op eq "export") {
Link Here
|
97 |
( $query->param("end_accession") ) |
171 |
( $query->param("end_accession") ) |
98 |
? C4::Dates->new( $query->param("end_accession") ) |
172 |
? C4::Dates->new( $query->param("end_accession") ) |
99 |
: ''; |
173 |
: ''; |
100 |
my $dont_export_items = $query->param("dont_export_item"); |
174 |
$dont_export_items = $query->param("dont_export_item") unless ($commandline); |
101 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
175 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
102 |
|
176 |
|
|
|
177 |
my $biblioitemstable = ($commandline and $deleted_barcodes) |
178 |
? 'deletedbiblioitems' |
179 |
: 'biblioitems'; |
180 |
my $itemstable = ($commandline and $deleted_barcodes) |
181 |
? 'deleteditems' |
182 |
: 'items'; |
183 |
|
103 |
my $starting_authid = $query->param('starting_authid'); |
184 |
my $starting_authid = $query->param('starting_authid'); |
104 |
my $ending_authid = $query->param('ending_authid'); |
185 |
my $ending_authid = $query->param('ending_authid'); |
105 |
my $authtype = $query->param('authtype'); |
186 |
my $authtype = $query->param('authtype'); |
106 |
|
187 |
|
107 |
if ( $record_type eq 'bibs' ) { |
188 |
if ( $record_type eq 'bibs' ) { |
108 |
my $items_filter = |
189 |
if ($timestamp) { |
109 |
$branch || $start_callnumber || $end_callnumber || |
190 |
# Specific query when timestamp is used |
110 |
$start_accession || $end_accession || |
191 |
# Actually it's used only with CLI and so all previous filters |
111 |
($itemtype && C4::Context->preference('item-level_itypes')); |
192 |
# are not used. |
112 |
$sql_query = $items_filter ? |
193 |
# If one day timestamp is used via the web interface, this part will |
113 |
"SELECT DISTINCT biblioitems.biblionumber |
194 |
# certainly have to be rewrited |
114 |
FROM biblioitems JOIN items |
195 |
$sql_query = " ( |
115 |
USING (biblionumber) WHERE 1" |
196 |
SELECT biblionumber |
116 |
: |
197 |
FROM $biblioitemstable |
117 |
"SELECT biblioitems.biblionumber FROM biblioitems WHERE biblionumber >0 "; |
198 |
LEFT JOIN items USING(biblionumber) |
118 |
|
199 |
WHERE $biblioitemstable.timestamp >= ? |
119 |
if ( $StartingBiblionumber ) { |
200 |
OR items.timestamp >= ? |
120 |
$sql_query .= " AND biblioitems.biblionumber >= ? "; |
201 |
) UNION ( |
121 |
push @sql_params, $StartingBiblionumber; |
202 |
SELECT biblionumber |
122 |
} |
203 |
FROM $biblioitemstable |
|
|
204 |
LEFT JOIN deleteditems USING(biblionumber) |
205 |
WHERE $biblioitemstable.timestamp >= ? |
206 |
OR deleteditems.timestamp >= ? |
207 |
) "; |
208 |
my $ts = $timestamp->output('iso'); |
209 |
@sql_params = ($ts, $ts, $ts, $ts); |
210 |
} else { |
211 |
my $items_filter = |
212 |
$branch || $start_callnumber || $end_callnumber || |
213 |
$start_accession || $timestamp || $end_accession || |
214 |
($itemtype && C4::Context->preference('item-level_itypes')); |
215 |
$sql_query = $items_filter ? |
216 |
"SELECT DISTINCT $biblioitemstable.biblionumber |
217 |
FROM $biblioitemstable JOIN $itemstable |
218 |
USING (biblionumber) WHERE 1" |
219 |
: |
220 |
"SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 "; |
221 |
|
222 |
if ( $StartingBiblionumber ) { |
223 |
$sql_query .= " AND $biblioitemstable.biblionumber >= ? "; |
224 |
push @sql_params, $StartingBiblionumber; |
225 |
} |
123 |
|
226 |
|
124 |
if ( $EndingBiblionumber ) { |
227 |
if ( $EndingBiblionumber ) { |
125 |
$sql_query .= " AND biblioitems.biblionumber <= ? "; |
228 |
$sql_query .= " AND $biblioitemstable.biblionumber <= ? "; |
126 |
push @sql_params, $EndingBiblionumber; |
229 |
push @sql_params, $EndingBiblionumber; |
127 |
} |
230 |
} |
128 |
|
231 |
|
129 |
if ($branch) { |
232 |
if ($branch) { |
130 |
$sql_query .= " AND homebranch = ? "; |
233 |
$sql_query .= " AND homebranch = ? "; |
131 |
push @sql_params, $branch; |
234 |
push @sql_params, $branch; |
132 |
} |
235 |
} |
133 |
|
236 |
|
134 |
if ($start_callnumber) { |
237 |
if ($start_callnumber) { |
135 |
$sql_query .= " AND itemcallnumber <= ? "; |
238 |
$sql_query .= " AND itemcallnumber <= ? "; |
136 |
push @sql_params, $start_callnumber; |
239 |
push @sql_params, $start_callnumber; |
137 |
} |
240 |
} |
138 |
|
241 |
|
139 |
if ($end_callnumber) { |
242 |
if ($end_callnumber) { |
140 |
$sql_query .= " AND itemcallnumber >= ? "; |
243 |
$sql_query .= " AND itemcallnumber >= ? "; |
141 |
push @sql_params, $end_callnumber; |
244 |
push @sql_params, $end_callnumber; |
142 |
} |
245 |
} |
143 |
if ($start_accession) { |
246 |
if ($start_accession) { |
144 |
$sql_query .= " AND dateaccessioned >= ? "; |
247 |
$sql_query .= " AND dateaccessioned >= ? "; |
145 |
push @sql_params, $start_accession->output('iso'); |
248 |
push @sql_params, $start_accession->output('iso'); |
146 |
} |
249 |
} |
147 |
|
250 |
|
148 |
if ($end_accession) { |
251 |
if ($end_accession) { |
149 |
$sql_query .= " AND dateaccessioned <= ? "; |
252 |
$sql_query .= " AND dateaccessioned <= ? "; |
150 |
push @sql_params, $end_accession->output('iso'); |
253 |
push @sql_params, $end_accession->output('iso'); |
151 |
} |
254 |
} |
152 |
|
255 |
|
153 |
if ( $itemtype ) { |
256 |
if ( $itemtype ) { |
154 |
$sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?"; |
257 |
$sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?"; |
155 |
push @sql_params, $itemtype; |
258 |
push @sql_params, $itemtype; |
|
|
259 |
} |
156 |
} |
260 |
} |
157 |
} |
261 |
} |
158 |
elsif ( $record_type eq 'auths' ) { |
262 |
elsif ( $record_type eq 'auths' ) { |
Lines 207-267
if ($op eq "export") {
Link Here
|
207 |
$sth->execute(@sql_params); |
311 |
$sth->execute(@sql_params); |
208 |
|
312 |
|
209 |
while ( my ($recordid) = $sth->fetchrow ) { |
313 |
while ( my ($recordid) = $sth->fetchrow ) { |
210 |
my $record; |
314 |
if ( $deleted_barcodes ) { |
211 |
if ( $record_type eq 'bibs' ) { |
315 |
my $q = " |
212 |
$record = eval { GetMarcBiblio($recordid); }; |
316 |
SELECT DISTINCT barcode |
213 |
|
317 |
FROM deleteditems |
214 |
# FIXME: decide how to handle records GetMarcBiblio can't parse or retrieve |
318 |
WHERE deleteditems.biblionumber = ? |
215 |
if ($@) { |
319 |
"; |
216 |
next; |
320 |
my $sth = $dbh->prepare($q); |
|
|
321 |
$sth->execute($recordid); |
322 |
while (my $row = $sth->fetchrow_array) { |
323 |
print "$row\n"; |
217 |
} |
324 |
} |
218 |
next if not defined $record; |
325 |
} else { |
219 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid ) |
326 |
my $record; |
220 |
unless $dont_export_items; |
327 |
if ( $record_type eq 'bibs' ) { |
221 |
if ( $strip_nonlocal_items || $limit_ind_branch ) { |
328 |
$record = eval { GetMarcBiblio($recordid); }; |
222 |
my ( $homebranchfield, $homebranchsubfield ) = |
329 |
|
223 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
330 |
if ($@) { |
224 |
for my $itemfield ( $record->field($homebranchfield) ) { |
331 |
next; |
225 |
|
332 |
} |
226 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
333 |
next if not defined $record; |
227 |
$branch = C4::Context->userenv->{'branch'} unless $branch; |
334 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid ) |
228 |
$record->delete_field($itemfield) |
335 |
unless $dont_export_items; |
229 |
if ( |
336 |
if ( $strip_nonlocal_items || $limit_ind_branch ) { |
230 |
$itemfield->subfield($homebranchsubfield) ne $branch ); |
337 |
my ( $homebranchfield, $homebranchsubfield ) = |
|
|
338 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
339 |
for my $itemfield ( $record->field($homebranchfield) ) { |
340 |
|
341 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
342 |
$branch = C4::Context->userenv->{'branch'} unless $branch; |
343 |
$record->delete_field($itemfield) |
344 |
if ( |
345 |
$itemfield->subfield($homebranchsubfield) ne $branch ); |
346 |
} |
231 |
} |
347 |
} |
232 |
} |
348 |
} |
233 |
} |
349 |
elsif ( $record_type eq 'auths' ) { |
234 |
elsif ( $record_type eq 'auths' ) { |
350 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
235 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
351 |
next if not defined $record; |
236 |
next if not defined $record; |
352 |
} |
237 |
} |
|
|
238 |
|
353 |
|
239 |
if ( $dont_export_fields ) { |
354 |
if ( $dont_export_fields ) { |
240 |
my @fields = split " ", $dont_export_fields; |
355 |
my @fields = split " ", $dont_export_fields; |
241 |
foreach ( @fields ) { |
356 |
foreach ( @fields ) { |
242 |
/^(\d*)(\w)?$/; |
357 |
/^(\d*)(\w)?$/; |
243 |
my $field = $1; |
358 |
my $field = $1; |
244 |
my $subfield = $2; |
359 |
my $subfield = $2; |
245 |
# skip if this record doesn't have this field |
360 |
# skip if this record doesn't have this field |
246 |
next if not defined $record->field($field); |
361 |
next if not defined $record->field($field); |
247 |
if( $subfield ) { |
362 |
if( $subfield ) { |
248 |
$record->field($field)->delete_subfields($subfield); |
363 |
$record->field($field)->delete_subfields($subfield); |
|
|
364 |
} |
365 |
else { |
366 |
$record->delete_field($record->field($field)); |
367 |
} |
249 |
} |
368 |
} |
250 |
else { |
369 |
} |
251 |
$record->delete_field($record->field($field)); |
370 |
RemoveAllNsb($record) if ($clean); |
|
|
371 |
if ( $output_format eq "xml" ) { |
372 |
if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') { |
373 |
print $record->as_xml_record('UNIMARCAUTH'); |
374 |
} else { |
375 |
print $record->as_xml_record($marcflavour); |
252 |
} |
376 |
} |
253 |
} |
377 |
} |
254 |
} |
378 |
else { |
255 |
if ( $output_format eq "xml" ) { |
379 |
print $record->as_usmarc(); |
256 |
if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') { |
|
|
257 |
print $record->as_xml_record('UNIMARCAUTH'); |
258 |
} else { |
259 |
print $record->as_xml_record($marcflavour); |
260 |
} |
380 |
} |
261 |
} |
381 |
} |
262 |
else { |
|
|
263 |
print $record->as_usmarc(); |
264 |
} |
265 |
} |
382 |
} |
266 |
exit; |
383 |
exit; |
267 |
|
384 |
|
Lines 279-284
else {
Link Here
|
279 |
); |
396 |
); |
280 |
push @itemtypesloop, \%row; |
397 |
push @itemtypesloop, \%row; |
281 |
} |
398 |
} |
|
|
399 |
my $branches = GetBranches($limit_ind_branch); |
282 |
my @branchloop; |
400 |
my @branchloop; |
283 |
for my $thisbranch ( |
401 |
for my $thisbranch ( |
284 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
402 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
Lines 317-322
else {
Link Here
|
317 |
itemtypeloop => \@itemtypesloop, |
435 |
itemtypeloop => \@itemtypesloop, |
318 |
DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), |
436 |
DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar(), |
319 |
authtypeloop => \@authtypesloop, |
437 |
authtypeloop => \@authtypesloop, |
|
|
438 |
dont_export_fields => C4::Context->preference("DontExportFields"), |
320 |
); |
439 |
); |
321 |
|
440 |
|
322 |
output_html_with_http_headers $query, $cookie, $template->output; |
441 |
output_html_with_http_headers $query, $cookie, $template->output; |
323 |
- |
|
|