MT2116: Addons to the CSV export
Add user-defined headers Add CSV, field and subfield separator selection
This commit is contained in:
parent
85983247e4
commit
0865bd7727
13
C4/Csv.pm
13
C4/Csv.pm
|
|
@ -31,6 +31,7 @@ $VERSION = 3.00;
|
|||
|
||||
@EXPORT = qw(
|
||||
&GetCsvProfiles
|
||||
&GetCsvProfile
|
||||
&GetCsvProfilesLoop
|
||||
&GetMarcFieldsForCsv
|
||||
);
|
||||
|
|
@ -49,6 +50,18 @@ sub GetCsvProfiles {
|
|||
|
||||
}
|
||||
|
||||
# Returns all informations about a given csv profile
|
||||
sub GetCsvProfile {
|
||||
my ($id) = @_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $query = "SELECT * FROM export_format WHERE export_format_id=?";
|
||||
|
||||
$sth = $dbh->prepare($query);
|
||||
$sth->execute($id);
|
||||
|
||||
return ($sth->fetchrow_hashref);
|
||||
}
|
||||
|
||||
# Returns fields to extract for the given csv profile
|
||||
sub GetMarcFieldsForCsv {
|
||||
|
||||
|
|
|
|||
79
C4/Record.pm
79
C4/Record.pm
|
|
@ -341,6 +341,8 @@ C<$record> - a MARC::Record object
|
|||
|
||||
C<$csvprofileid> - the id of the CSV profile to use for the export (see export_format.export_format_id and the GetCsvProfiles function in C4::Csv)
|
||||
|
||||
C<$header> - true if the headers are to be printed (typically at first pass)
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
|
@ -351,36 +353,72 @@ C<$csvprofileid> - the id of the CSV profile to use for the export (see export_f
|
|||
sub marc2csv {
|
||||
my ($record, $id, $header) = @_;
|
||||
my $output;
|
||||
my $csv = Text::CSV->new();
|
||||
|
||||
# Get the information about the csv profile
|
||||
my $marcfieldslist = GetMarcFieldsForCsv($id);
|
||||
my $profile = GetCsvProfile($id);
|
||||
|
||||
# Getting separators
|
||||
my $csvseparator = $profile->{csv_separator} || ',';
|
||||
my $fieldseparator = $profile->{field_separator} || '#';
|
||||
my $subfieldseparator = $profile->{subfield_separator} || '|';
|
||||
|
||||
# TODO: Be more generic (in case we have to handle other protected chars or more separators)
|
||||
if ($csvseparator eq '\t') { $csvseparator = "\t" }
|
||||
if ($fieldseparator eq '\t') { $fieldseparator = "\t" }
|
||||
if ($subfieldseparator eq '\t') { $subfieldseparator = "\t" }
|
||||
|
||||
# Init CSV
|
||||
my $csv = Text::CSV->new({ sep_char => $csvseparator });
|
||||
|
||||
# Getting the marcfields
|
||||
my $marcfieldslist = $profile->{marcfields};
|
||||
|
||||
# Getting the marcfields as an array
|
||||
my @marcfields = split('\|', $marcfieldslist);
|
||||
my @marcfieldsarray = split('\|', $marcfieldslist);
|
||||
|
||||
# Separating the marcfields from the the user-supplied headers
|
||||
my @marcfields;
|
||||
foreach (@marcfieldsarray) {
|
||||
my @result = split('=', $_);
|
||||
if (scalar(@result) == 2) {
|
||||
push @marcfields, { header => $result[0], field => $result[1] };
|
||||
} else {
|
||||
push @marcfields, { field => $result[0] }
|
||||
}
|
||||
}
|
||||
|
||||
# If we have to insert the headers
|
||||
if ($header) {
|
||||
my @marcfieldsheaders;
|
||||
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
||||
# For each field or subfield
|
||||
foreach (@marcfields) {
|
||||
# We get the matching tag name
|
||||
if (index($_, '$') > 0) {
|
||||
my ($fieldtag, $subfieldtag) = split('\$', $_);
|
||||
my $query = "SELECT liblibrarian FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($fieldtag, $subfieldtag);
|
||||
my @results = $sth->fetchrow_array();
|
||||
push @marcfieldsheaders, @results[0];
|
||||
|
||||
my $field = $_->{field};
|
||||
|
||||
# If we have a user-supplied header, we use it
|
||||
if (exists $_->{header}) {
|
||||
push @marcfieldsheaders, $_->{header};
|
||||
} else {
|
||||
my $query = "SELECT liblibrarian FROM marc_tag_structure WHERE tagfield=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($_);
|
||||
my @results = $sth->fetchrow_array();
|
||||
push @marcfieldsheaders, @results[0];
|
||||
warn "else";
|
||||
# If not, we get the matching tag name from koha
|
||||
if (index($field, '$') > 0) {
|
||||
my ($fieldtag, $subfieldtag) = split('\$', $field);
|
||||
my $query = "SELECT liblibrarian FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($fieldtag, $subfieldtag);
|
||||
my @results = $sth->fetchrow_array();
|
||||
warn "subfield $fieldtag, $subfieldtag";
|
||||
push @marcfieldsheaders, $results[0];
|
||||
} else {
|
||||
my $query = "SELECT liblibrarian FROM marc_tag_structure WHERE tagfield=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($field);
|
||||
my @results = $sth->fetchrow_array();
|
||||
warn "field $results[0]";
|
||||
push @marcfieldsheaders, $results[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
$csv->combine(@marcfieldsheaders);
|
||||
|
|
@ -389,7 +427,8 @@ sub marc2csv {
|
|||
|
||||
# For each marcfield to export
|
||||
my @fieldstab;
|
||||
foreach my $marcfield (@marcfields) {
|
||||
foreach (@marcfields) {
|
||||
my $marcfield = $_->{field};
|
||||
# If it is a subfield
|
||||
if (index($marcfield, '$') > 0) {
|
||||
my ($fieldtag, $subfieldtag) = split('\$', $marcfield);
|
||||
|
|
@ -405,11 +444,11 @@ sub marc2csv {
|
|||
push @tmpfields, $subfield;
|
||||
}
|
||||
}
|
||||
push (@fieldstab, join(',', @tmpfields));
|
||||
push (@fieldstab, join($subfieldseparator, @tmpfields));
|
||||
# Or a field
|
||||
} else {
|
||||
my @fields = ($record->field($marcfield));
|
||||
push (@fieldstab, join(',', map($_->as_string(), @fields)));
|
||||
push (@fieldstab, join($fieldseparator, map($_->as_string(), @fields)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2975,6 +2975,18 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
|
|||
|
||||
|
||||
|
||||
$DBversion = "3.01.00.101";
|
||||
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
|
||||
$dbh->do(qq{
|
||||
ALTER TABLE `export_format` ADD `csv_separator` VARCHAR( 2 ) NOT NULL AFTER `marcfields` ,
|
||||
ADD `field_separator` VARCHAR( 2 ) NOT NULL AFTER `csv_separator` ,
|
||||
ADD `subfield_separator` VARCHAR( 2 ) NOT NULL AFTER `field_separator`
|
||||
});
|
||||
print "Upgrade done (added separators for csv export)\n";
|
||||
SetVersion ($DBversion);
|
||||
}
|
||||
|
||||
|
||||
=item DropAllForeignKeys($table)
|
||||
|
||||
Drop all foreign keys of the table $table
|
||||
|
|
|
|||
|
|
@ -49,8 +49,48 @@ function reloadPage(p) {
|
|||
<label for="profile_description">Profile description :</label>
|
||||
<textarea cols="50" name="profile_description" id="profile_description"></textarea><br /><br />
|
||||
|
||||
<label for="csv">CSV separator :</label>
|
||||
<select name="csv_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value="," selected="selected">Comma (,)</option>
|
||||
<option value="|">Pipe (|)</option>
|
||||
<option value=";">Semi-colon (;)</option>
|
||||
<option value="#">Sharp (#)</option>
|
||||
<option value=" ">Space ( )</option>
|
||||
<option value="\t">Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
<label for="field_separator">Field separator :</label>
|
||||
<select name="field_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value=",">Comma (,)</option>
|
||||
<option value="|">Pipe (|)</option>
|
||||
<option value=";">Semi-colon (;)</option>
|
||||
<option value="#" selected="selected">Sharp (#)</option>
|
||||
<option value=" ">Space ( )</option>
|
||||
<option value="\t">Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
<label for="subfield_separator">Subfield separator :</label>
|
||||
<select name="subfield_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value=",">Comma (,)</option>
|
||||
<option value="|" selected="selected">Pipe (|)</option>
|
||||
<option value=";">Semi-colon (;)</option>
|
||||
<option value="#">Sharp (#)</option>
|
||||
<option value=" ">Space ( )</option>
|
||||
<option value="\t">Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
<label for="profile_content">Profile marcfields :</label>
|
||||
<textarea cols="50" name="profile_content" id="profile_content"></textarea>
|
||||
<textarea cols="50" rows="2" name="profile_content" id="profile_content"></textarea>
|
||||
<p>You have to define which fields or subfields you want to export, separated by pipes.<br />
|
||||
You can also use your own headers (instead of the ones from koha) by prefixing the field number with an header, followed by the equal sign.<br />
|
||||
Example : Personal name=200|Entry element=210$a|300
|
||||
</p>
|
||||
</fieldset>
|
||||
<input type="hidden" name="action" value="create" />
|
||||
<input type="submit" />
|
||||
|
|
@ -59,7 +99,7 @@ function reloadPage(p) {
|
|||
|
||||
<!-- TMPL_IF NAME="existing_profiles" -->
|
||||
<br /><br />
|
||||
<h1>Modify or delete an existing profile</h1>
|
||||
<h1 id="modify">Modify or delete an existing profile</h1>
|
||||
|
||||
<form action="/cgi-bin/koha/tools/csv-profiles.pl" method="post">
|
||||
<fieldset class="brief">
|
||||
|
|
@ -74,6 +114,44 @@ function reloadPage(p) {
|
|||
<label for="modify_profile_description">Profile description :</label>
|
||||
<textarea cols="50" name="profile_description" id="modify_profile_description"><!-- TMPL_VAR NAME="selected_profile_description" --></textarea><br /><br />
|
||||
|
||||
<label for="csv">CSV separator :</label>
|
||||
<select name="csv_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value=","<!-- TMPL_IF EXPR="selected_csv_separator eq ','" --> selected="selected"<!-- /TMPL_IF -->>Comma (,)</option>
|
||||
<option value="|"<!-- TMPL_IF EXPR="selected_csv_separator eq '|'" --> selected="selected"<!-- /TMPL_IF -->>Pipe (|)</option>
|
||||
<option value=";"<!-- TMPL_IF EXPR="selected_csv_separator eq ';'" --> selected="selected"<!-- /TMPL_IF -->>Semi-colon (;)</option>
|
||||
<option value="#"<!-- TMPL_IF EXPR="selected_csv_separator eq '#'" --> selected="selected"<!-- /TMPL_IF -->>Sharp (#)</option>
|
||||
<option value=" "<!-- TMPL_IF EXPR="selected_csv_separator eq ' '" --> selected="selected"<!-- /TMPL_IF -->>Space ( )</option>
|
||||
<option value="\t"<!-- TMPL_IF EXPR="selected_csv_separator eq '\t'" --> selected="selected"<!-- /TMPL_IF -->>Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
|
||||
<label for="field_separator">Field separator :</label>
|
||||
<select name="field_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value=","<!-- TMPL_IF EXPR="selected_field_separator eq ','" --> selected="selected"<!-- /TMPL_IF -->>Comma (,)</option>
|
||||
<option value="|"<!-- TMPL_IF EXPR="selected_field_separator eq '|'" --> selected="selected"<!-- /TMPL_IF -->>Pipe (|)</option>
|
||||
<option value=";"<!-- TMPL_IF EXPR="selected_field_separator eq ';'" --> selected="selected"<!-- /TMPL_IF -->>Semi-colon (;)</option>
|
||||
<option value="#"<!-- TMPL_IF EXPR="selected_field_separator eq '#'" --> selected="selected"<!-- /TMPL_IF -->>Sharp (#)</option>
|
||||
<option value=" "<!-- TMPL_IF EXPR="selected_field_separator eq ' '" --> selected="selected"<!-- /TMPL_IF -->>Space ( )</option>
|
||||
<option value="\t"<!-- TMPL_IF EXPR="selected_field_separator eq '\t'" --> selected="selected"<!-- /TMPL_IF -->>Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
<label for="subfield_separator">Subfield separator :</label>
|
||||
<select name="subfield_separator">
|
||||
<option value=";">Colon (:)</option>
|
||||
<option value=","<!-- TMPL_IF EXPR="selected_subfield_separator eq ','" --> selected="selected"<!-- /TMPL_IF -->>Comma (,)</option>
|
||||
<option value="|"<!-- TMPL_IF EXPR="selected_subfield_separator eq '|'" --> selected="selected"<!-- /TMPL_IF -->>Pipe (|)</option>
|
||||
<option value=";"<!-- TMPL_IF EXPR="selected_subfield_separator eq ';'" --> selected="selected"<!-- /TMPL_IF -->>Semi-colon (;)</option>
|
||||
<option value="#"<!-- TMPL_IF EXPR="selected_subfield_separator eq '#'" --> selected="selected"<!-- /TMPL_IF -->>Sharp (#)</option>
|
||||
<option value=" "<!-- TMPL_IF EXPR="selected_subfield_separator eq ' '" --> selected="selected"<!-- /TMPL_IF -->>Space ( )</option>
|
||||
<option value="\t"<!-- TMPL_IF EXPR="selected_subfield_separator eq '\t'" --> selected="selected"<!-- /TMPL_IF -->>Tabulation (\t)</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
|
||||
|
||||
<label for="modify_profile_content">Profile marcfields :</label>
|
||||
<textarea cols="50" name="profile_content" id="modify_profile_content"><!-- TMPL_VAR NAME="selected_profile_marcfields" --></textarea><br /><br />
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $string = $ARGV[0];
|
||||
|
||||
# Getting the marcfields as an array
|
||||
my @marcfieldsarray = split('\|', $string);
|
||||
|
||||
# Separating the marcfields from the the user-supplied headers
|
||||
my @marcfields;
|
||||
foreach (@marcfieldsarray) {
|
||||
my @result = split('=', $_);
|
||||
if (scalar(@result) == 2) {
|
||||
push @marcfields, { header => $result[0], field => $result[1] };
|
||||
} else {
|
||||
push @marcfields, { field => $result[0] }
|
||||
}
|
||||
}
|
||||
|
||||
use Data::Dumper;
|
||||
print Dumper(@marcfields);
|
||||
|
||||
|
||||
foreach (@marcfields) {
|
||||
print $_->{field};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -63,6 +63,9 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
|
|||
my $profile_name = $input->param("profile_name");
|
||||
my $profile_description = $input->param("profile_description");
|
||||
my $profile_content = $input->param("profile_content");
|
||||
my $csv_separator = $input->param("csv_separator");
|
||||
my $field_separator = $input->param("field_separator");
|
||||
my $subfield_separator = $input->param("subfield_separator");
|
||||
my $action = $input->param("action");
|
||||
my $delete = $input->param("delete");
|
||||
my $id = $input->param("id");
|
||||
|
|
@ -72,17 +75,17 @@ if ($profile_name && $profile_content && $action) {
|
|||
my $rows;
|
||||
|
||||
if ($action eq "create") {
|
||||
my $query = "INSERT INTO export_format(export_format_id, profile, description, marcfields) VALUES (NULL, ?, ?, ?)";
|
||||
my $query = "INSERT INTO export_format(export_format_id, profile, description, marcfields, csv_separator, field_separator, subfield_separator) VALUES (NULL, ?, ?, ?, ?, ?, ?)";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$rows = $sth->execute($profile_name, $profile_description, $profile_content);
|
||||
$rows = $sth->execute($profile_name, $profile_description, $profile_content, $csv_separator, $field_separator, $subfield_separator);
|
||||
|
||||
}
|
||||
|
||||
if ($action eq "edit") {
|
||||
my $query = "UPDATE export_format SET description=?, marcfields=? WHERE export_format_id=? LIMIT 1";
|
||||
my $query = "UPDATE export_format SET description=?, marcfields=?, csv_separator=?, field_separator=?, subfield_separator=? WHERE export_format_id=? LIMIT 1";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$rows = $sth->execute($profile_description, $profile_content, $profile_name);
|
||||
|
||||
$rows = $sth->execute($profile_description, $profile_content, $csv_separator, $field_separator, $subfield_separator, $profile_name);
|
||||
warn "id $id";
|
||||
}
|
||||
|
||||
if ($action eq "delete") {
|
||||
|
|
@ -100,17 +103,21 @@ if ($profile_name && $profile_content && $action) {
|
|||
|
||||
# If a profile has been selected for modification
|
||||
if ($id) {
|
||||
my $query = "SELECT export_format_id, profile, description, marcfields FROM export_format WHERE export_format_id = ?";
|
||||
my $query = "SELECT export_format_id, profile, description, marcfields, csv_separator, field_separator, subfield_separator FROM export_format WHERE export_format_id = ?";
|
||||
my $sth;
|
||||
$sth = $dbh->prepare($query);
|
||||
|
||||
$sth->execute($id);
|
||||
my $selected_profile = $sth->fetchrow_arrayref();
|
||||
warn "value : " . $selected_profile->[4];
|
||||
$template->param(
|
||||
selected_profile_id => $selected_profile->[0],
|
||||
selected_profile_name => $selected_profile->[1],
|
||||
selected_profile_description => $selected_profile->[2],
|
||||
selected_profile_marcfields => $selected_profile->[3]
|
||||
selected_profile_marcfields => $selected_profile->[3],
|
||||
selected_csv_separator => $selected_profile->[4],
|
||||
selected_field_separator => $selected_profile->[5],
|
||||
selected_subfield_separator => $selected_profile->[6]
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue