@@ -, +, @@ tabulation --- C4/Context.pm | 20 +++++++++++++++++++ Koha/Template/Plugin/Koha.pm | 16 +++++++++++++++ admin/aqplan.pl | 4 ++-- .../catalogue/itemsearch_item.csv.inc | 2 +- .../en/includes/csv_headers/acqui/basket.tt | 2 +- .../includes/csv_headers/acqui/basketgroup.tt | 2 +- .../includes/csv_headers/acqui/lateorders.tt | 2 +- .../csv_headers/catalogue/itemsearch.tt | 2 +- .../prog/en/modules/acqui/csv/basket.tt | 2 +- .../prog/en/modules/acqui/csv/basketgroup.tt | 2 +- .../prog/en/modules/acqui/csv/lateorders.tt | 2 +- misc/cronjobs/overdue_notices.pl | 5 ++--- misc/export_borrowers.pl | 3 +-- reports/acquisitions_stats.pl | 3 +-- reports/bor_issues_top.pl | 3 +-- reports/borrowers_out.pl | 3 +-- reports/borrowers_stats.pl | 3 +-- reports/cash_register_stats.pl | 2 +- reports/cat_issues_top.pl | 3 +-- reports/catalogue_stats.pl | 3 +-- reports/guided_reports.pl | 3 +-- reports/issues_avg_stats.pl | 3 +-- reports/issues_stats.pl | 3 +-- reports/orders_by_fund.pl | 4 ++-- reports/reserves_stats.pl | 3 +-- reports/serials_stats.pl | 3 +-- tools/viewlog.pl | 2 +- 27 files changed, 64 insertions(+), 41 deletions(-) --- a/C4/Context.pm +++ a/C4/Context.pm @@ -479,6 +479,26 @@ sub delete_preference { return 0; } +=head2 csv_delimiter + + $delimiter = C4::Context->csv_delimiter; + + Returns prefered CSV delimiter, using system preference 'CSVDelimiter'. + If this preference is missing or empty semicolon will be returned. + This method is needed because of special behavior for tabulation. + + You can, optionally, pass a value parameter to this routine + in the case of existing delimiter. + +=cut + +sub csv_delimiter { + my ( $self, $value ) = @_; + my $delimiter = $value || $self->preference('CSVDelimiter') || ';'; + $delimiter = "\t" if $delimiter eq 'tabulation'; + return $delimiter; +} + =head2 Zconn $Zconn = C4::Context->Zconn --- a/Koha/Template/Plugin/Koha.pm +++ a/Koha/Template/Plugin/Koha.pm @@ -55,6 +55,22 @@ sub Preference { return C4::Context->preference( $pref ); } +=head3 CSVDelimiter + +The delimiter option 'tabs' is stored in the DB as 'tabulation' to avoid issues +storing special characters in the DB. This helper function translates the value +to the correct character when used in templates. + +You can, optionally, pass a value parameter to this routine in the case of delimiter +being fetched in the scripts and still needing to be translated + +=cut + +sub CSVDelimiter { + my ( $self, $val ) = @_; + return C4::Context->csv_delimiter($val); +} + sub Version { my $version_string = Koha::version(); my ( $major, $minor, $maintenance, $development ) = split( '\.', $version_string ); --- a/admin/aqplan.pl +++ a/admin/aqplan.pl @@ -97,7 +97,7 @@ my $show_actual = $input->param('show_actual'); my $show_percent = $input->param('show_percent'); my $output = $input->param("output") // q{}; our $basename = $input->param("basename"); -our $del = $input->param("sep"); +our $del = C4::Context->csv_delimiter(scalar $input->param("sep")); my $show_mine = $input->param('show_mine') ; @@ -307,7 +307,7 @@ foreach my $n (@names) { # DEFAULT DISPLAY BEGINS my $CGIextChoice = ( 'CSV' ); # FIXME translation -my $CGIsepChoice = ( C4::Context->preference("CSVDelimiter") ); +my $CGIsepChoice = ( C4::Context->csv_delimiter ); my ( @budget_lines, %cell_hash ); --- a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/catalogue/itemsearch_item.csv.inc @@ -6,7 +6,7 @@ [%- USE AuthorisedValues -%] [%- SET biblio = item.biblio -%] [%- SET biblioitem = item.biblioitem -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] "[% biblio.title | replace('"', '""') | $raw %] [% IF ( Koha.Preference( 'marcflavour' ) == 'UNIMARC' && biblio.author ) %]by [% END %][% biblio.author | replace('"', '""') | $raw %]" [%- delimiter | $raw -%] "[% (biblioitem.publicationyear || biblio.copyrightdate) | replace('"', '""') | $raw %]" --- a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/basket.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/basket.tt @@ -1,4 +1,4 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- BLOCK -%]Contract name[% delimiter | html %]Order number[% delimiter | html %]Entry date[% delimiter | html %]ISBN[% delimiter | html %]Author[% delimiter | html %]Title[% delimiter | html %]Publication year[% delimiter | html %]Publisher[% delimiter | html %]Collection title[% delimiter | html %]Note for vendor[% delimiter | html %]Quantity[% delimiter | html %]RRP[% delimiter | html %]Delivery place[% delimiter | html %]Billing place[%- END -%] --- a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/basketgroup.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/basketgroup.tt @@ -1,4 +1,4 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- BLOCK -%]Account number[% delimiter | html %]Basket name[% delimiter | html %]Order number[% delimiter | html %]Author[% delimiter | html %]Title[% delimiter | html %]Publisher[% delimiter | html %]Publication year[% delimiter | html %]Collection title[% delimiter | html %]ISBN[% delimiter | html %]Quantity[% delimiter | html %]RRP tax included[% delimiter | html %]RRP tax excluded[% delimiter | html %]Discount[% delimiter | html %]Estimated cost tax included[% delimiter | html %]Estimated cost tax excluded[% delimiter | html %]Note for vendor[% delimiter | html %]Entry date[% delimiter | html %]Bookseller name[% delimiter | html %]Bookseller physical address[% delimiter | html %]Bookseller postal address[% delimiter | html %]Contract number[% delimiter | html %]Contract name[% delimiter | html %]Basket group delivery place[% delimiter | html %]Basket group billing place[% delimiter | html %]Basket delivery place[% delimiter | html %]Basket billing place[%- END -%] --- a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/lateorders.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/acqui/lateorders.tt @@ -1,4 +1,4 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference('CSVDelimiter') || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- BLOCK -%]ORDER DATE[%- delimiter | html -%]ESTIMATED DELIVERY DATE[%- delimiter | html -%]VENDOR[%- delimiter | html -%]INFORMATION[%- delimiter | html -%]TOTAL COST[%- delimiter | html -%]BASKET[%- delimiter | html -%]CLAIMS COUNT[%- delimiter | html -%]CLAIMED DATE[%- delimiter | html -%]INTERNAL NOTE[%- delimiter | html -%]VENDOR NOTE[%- delimiter | html -%]ISBN[%- END -%] --- a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/catalogue/itemsearch.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/csv_headers/catalogue/itemsearch.tt @@ -1,6 +1,6 @@ [%- USE raw -%] [%- USE Koha -%] -[%- SET delimiter = Koha.Preference('CSVDelimiter') || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- BLOCK -%] "Title" [%- delimiter | $raw -%] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/basket.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/basket.tt @@ -1,5 +1,5 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- INCLUDE csv_headers/acqui/basket.tt -%] [%- INCLUDE empty_line.inc -%] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/basketgroup.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/basketgroup.tt @@ -1,5 +1,5 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- USE Price -%] [%- INCLUDE csv_headers/acqui/basketgroup.tt -%] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/lateorders.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/csv/lateorders.tt @@ -1,5 +1,5 @@ [%- USE Koha -%] -[%- SET delimiter = Koha.Preference( 'CSVDelimiter' ) || ',' -%] +[%- SET delimiter = Koha.CSVDelimiter() -%] [%- USE KohaDates -%] [%- INCLUDE csv_headers/acqui/lateorders.tt -%] --- a/misc/cronjobs/overdue_notices.pl +++ a/misc/cronjobs/overdue_notices.pl @@ -404,8 +404,7 @@ binmode( STDOUT, ':encoding(UTF-8)' ); our $csv; # the Text::CSV_XS object our $csv_fh; # the filehandle to the CSV file. if ( defined $csvfilename ) { - my $sep_char = C4::Context->preference('CSVDelimiter') || ';'; - $sep_char = "\t" if ($sep_char eq 'tabulation'); + my $sep_char = C4::Context->csv_delimiter; $csv = Text::CSV_XS->new( { binary => 1 , sep_char => $sep_char } ); if ( $csvfilename eq '' ) { $csv_fh = *STDOUT; @@ -833,7 +832,7 @@ END_SQL # Generate the content of the csv with headers my $content; if ( defined $csvfilename ) { - my $delimiter = C4::Context->preference('CSVDelimiter') || ';'; + my $delimiter = C4::Context->csv_delimiter; $content = join($delimiter, qw(title name surname address1 address2 zipcode city country email itemcount itemsinfo due_date issue_date)) . "\n"; } else { --- a/misc/export_borrowers.pl +++ a/misc/export_borrowers.pl @@ -91,8 +91,7 @@ my $sth = $dbh->prepare($query); $sth->execute; unless ( $separator ) { - $separator = C4::Context->preference('CSVDelimiter') || ','; - $separator = "\t" if ($separator eq 'tabulation'); + $separator = C4::Context->csv_delimiter; } my $csv = Text::CSV->new( { sep_char => $separator, binary => 1 } ); --- a/reports/acquisitions_stats.pl +++ a/reports/acquisitions_stats.pl @@ -69,8 +69,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( } ); -our $sep = $input->param("sep") // ''; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param( do_it => $do_it, --- a/reports/bor_issues_top.pl +++ a/reports/bor_issues_top.pl @@ -54,8 +54,7 @@ my ($template, $borrowernumber, $cookie) type => "intranet", flagsrequired => {reports => '*'}, }); -our $sep = $input->param("sep") || C4::Context->preference('CSVDelimiter') || ','; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); if ($do_it) { --- a/reports/borrowers_out.pl +++ a/reports/borrowers_out.pl @@ -49,8 +49,7 @@ $filters[1] = eval { output_pref( { dt => dt_from_string( $filters[1]), dateonly my $output = $input->param("output"); my $basename = $input->param("basename"); -our $sep = $input->param("sep") || ''; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); my ($template, $borrowernumber, $cookie) = get_template_and_user({template_name => $fullreportname, query => $input, --- a/reports/borrowers_stats.pl +++ a/reports/borrowers_stats.pl @@ -58,8 +58,7 @@ my $borstat = $input->param("status"); my $borstat1 = $input->param("activity"); my $output = $input->param("output"); my $basename = $input->param("basename"); -our $sep = $input->param("sep"); -$sep = "\t" if ($sep and $sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); my ($template, $borrowernumber, $cookie) = get_template_and_user({template_name => $fullreportname, --- a/reports/cash_register_stats.pl +++ a/reports/cash_register_stats.pl @@ -157,7 +157,7 @@ if ($do_it) { my $format = 'csv'; my $reportname = $input->param('basename'); my $reportfilename = $reportname ? "$reportname.$format" : "reportresults.$format" ; - my $delimiter = C4::Context->preference('CSVDelimiter') || ','; + my $delimiter = C4::Context->csv_delimiter; my @rows; foreach my $row (@loopresult) { my @rowValues; --- a/reports/cat_issues_top.pl +++ a/reports/cat_issues_top.pl @@ -55,8 +55,7 @@ my ($template, $borrowernumber, $cookie) type => "intranet", flagsrequired => { reports => '*'}, }); -our $sep = $input->param("sep"); -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); if ($do_it) { --- a/reports/catalogue_stats.pl +++ a/reports/catalogue_stats.pl @@ -50,8 +50,7 @@ my @filters = $input->multi_param("Filter"); my $cotedigits = $input->param("cotedigits"); my $output = $input->param("output"); my $basename = $input->param("basename"); -our $sep = $input->param("sep"); -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); my $item_itype; if(C4::Context->preference('item-level_itypes')) { $item_itype = "items\.itype" --- a/reports/guided_reports.pl +++ a/reports/guided_reports.pl @@ -931,9 +931,8 @@ elsif ($phase eq 'Export'){ $content .= join("\t", map { $_ // '' } @$row) . "\n"; } } else { - my $delimiter = C4::Context->preference('CSVDelimiter') || ','; if ( $format eq 'csv' ) { - $delimiter = "\t" if $delimiter eq 'tabulation'; + my $delimiter = C4::Context->csv_delimiter; $type = 'application/csv'; my $csv = Text::CSV::Encoded->new({ encoding_out => 'UTF-8', sep_char => $delimiter}); $csv or die "Text::CSV::Encoded->new({binary => 1}) FAILED: " . Text::CSV::Encoded->error_diag(); --- a/reports/issues_avg_stats.pl +++ a/reports/issues_avg_stats.pl @@ -66,8 +66,7 @@ my ($template, $borrowernumber, $cookie) type => "intranet", flagsrequired => {reports => '*'}, }); -our $sep = $input->param("sep"); -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); if ($do_it) { --- a/reports/issues_stats.pl +++ a/reports/issues_stats.pl @@ -75,8 +75,7 @@ my ($template, $borrowernumber, $cookie) = get_template_and_user({ type => "intranet", flagsrequired => {reports => '*'}, }); -our $sep = $input->param("sep") // ';'; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); --- a/reports/orders_by_fund.pl +++ a/reports/orders_by_fund.pl @@ -32,6 +32,7 @@ use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); use C4::Budgets qw( GetBudgetsReport GetBudgetHierarchy ); use C4::Acquisition qw( GetBasket get_rounded_price ); +use C4::Context; use Koha::Biblios; use Koha::DateUtils qw( dt_from_string output_pref ); @@ -131,8 +132,7 @@ if ( $get_orders ) { # If we are outputting to a file, create it and exit. else { my $basename = $params->{"basename"}; - my $sep = $params->{"sep"}; - $sep = "\t" if ($sep eq 'tabulation'); + my $sep = C4::Context->csv_delimiter(scalar $params->{"sep"}); # TODO Use Text::CSV to generate the CSV file print $query->header( --- a/reports/reserves_stats.pl +++ a/reports/reserves_stats.pl @@ -65,8 +65,7 @@ my ($template, $borrowernumber, $cookie) = get_template_and_user({ type => "intranet", flagsrequired => {reports => '*'}, }); -our $sep = $input->param("sep") || ''; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); $template->param(do_it => $do_it, ); --- a/reports/serials_stats.pl +++ a/reports/serials_stats.pl @@ -42,8 +42,7 @@ my $expired = $input->param("expired"); my $order = $input->param("order"); my $output = $input->param("output"); my $basename = $input->param("basename"); -our $sep = $input->param("sep") || ''; -$sep = "\t" if ($sep eq 'tabulation'); +our $sep = C4::Context->csv_delimiter(scalar $input->param("sep")); my ($template, $borrowernumber, $cookie) = get_template_and_user({template_name => $templatename, --- a/tools/viewlog.pl +++ a/tools/viewlog.pl @@ -229,8 +229,8 @@ if ($do_it) { # Printing to a csv file my $content = q{}; - my $delimiter = C4::Context->preference('CSVDelimiter') || ','; if (@data) { + my $delimiter = C4::Context->csv_delimiter; my $csv = Text::CSV::Encoded->new( { encoding_out => 'utf8', sep_char => $delimiter } ); $csv or die "Text::CSV::Encoded->new FAILED: " . Text::CSV::Encoded->error_diag(); --