X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FOutput.pm;h=71f82e8a8757c40f5e04007d8bcaab6653ede4ec;hb=870191d40611e3e7414388d4dd911446a2059225;hp=8cfa35192c61133d0f55b3603a658b62a99bf78e;hpb=b1e2fa8fcaad4d8649e185fbcce2c7210bd8d40a;p=koha.git diff --git a/C4/Output.pm b/C4/Output.pm index 8cfa35192c..71f82e8a87 100644 --- a/C4/Output.pm +++ b/C4/Output.pm @@ -8,18 +8,18 @@ package C4::Output; # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . # NOTE: I'm pretty sure this module is deprecated in favor of @@ -28,30 +28,29 @@ package C4::Output; use strict; #use warnings; FIXME - Bug 2505 +use URI::Escape; + use C4::Context; -use C4::Dates qw(format_date); -use C4::Budgets qw(GetCurrency); use C4::Templates; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); +use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); BEGIN { - # set the version for version checking - $VERSION = 3.07.00.049; require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead - %EXPORT_TAGS = ( all =>[qw(&themelanguage &gettemplate setlanguagecookie pagination_bar &gettemplate + %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar parametrized_url &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)], ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)], html =>[qw(&output_with_http_headers &output_html_with_http_headers)] ); push @EXPORT, qw( - &themelanguage &gettemplate setlanguagecookie getlanguagecookie pagination_bar &gettemplate + setlanguagecookie getlanguagecookie pagination_bar parametrized_url ); push @EXPORT, qw( - &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber + &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers + &output_and_exit_if_error &output_and_exit ); } @@ -63,47 +62,6 @@ C4::Output - Functions for managing output, is slowly being deprecated =head1 FUNCTIONS =over 2 -=cut - -=item FormatNumber -=cut -sub FormatNumber{ -my $cur = GetCurrency; -my $cur_format = C4::Context->preference("CurrencyFormat"); -my $num; - -if ( $cur_format eq 'FR' ) { - $num = new Number::Format( - 'decimal_fill' => '2', - 'decimal_point' => ',', - 'int_curr_symbol' => $cur->{symbol}, - 'mon_thousands_sep' => ' ', - 'thousands_sep' => ' ', - 'mon_decimal_point' => ',' - ); -} else { # US by default.. - $num = new Number::Format( - 'int_curr_symbol' => '', - 'mon_thousands_sep' => ',', - 'mon_decimal_point' => '.' - ); -} -return $num; -} - -=item FormatData - -FormatData($data_hashref) -C<$data_hashref> is a ref to data to format - -Format dates of data those dates are assumed to contain date in their noun -Could be used in order to centralize all the formatting for HTML output -=cut - -sub FormatData{ - my $data_hashref=shift; - $$data_hashref{$_} = format_date( $$data_hashref{$_} ) for grep{/date/} keys (%$data_hashref); -} =item pagination_bar @@ -125,10 +83,11 @@ This function returns HTML, without any language dependency. =cut sub pagination_bar { - my $base_url = (@_ ? shift : $ENV{SCRIPT_NAME} . $ENV{QUERY_STRING}) or return undef; + my $base_url = (@_ ? shift : return); my $nb_pages = (@_) ? shift : 1; my $current_page = (@_) ? shift : undef; # delay default until later my $startfrom_name = (@_) ? shift : 'page'; + my $additional_parameters = shift || {}; # how many pages to show before and after the current page? my $pages_around = 2; @@ -145,6 +104,10 @@ sub pagination_bar { $base_url =~ s/$delim$//; # remove trailing delim my $url = $base_url . (($base_url =~ m/$delim/ or $base_url =~ m/\?/) ? '&' : '?' ) . $startfrom_name . '='; + my $url_suffix; + while ( my ( $k, $v ) = each %$additional_parameters ) { + $url_suffix .= '&' . $k . '=' . $v; + } my $pagination_bar = ''; # navigation bar useful only if more than one page to display ! @@ -156,7 +119,9 @@ sub pagination_bar { "\n" . ' ' . '' + . '1' + . $url_suffix + . '"rel="start">' . '<<' . ''; } else { @@ -173,6 +138,7 @@ sub pagination_bar { . ''; } else { @@ -211,7 +177,9 @@ sub pagination_bar { "\n" . ' ' . '' + . $page_number + . $url_suffix + . '">' . $page_number . ''; } $last_displayed_page = $page_number; @@ -226,6 +194,7 @@ sub pagination_bar { . ' '; } else { @@ -239,6 +208,7 @@ sub pagination_bar { . ' ' . '>>' . ''; } @@ -253,7 +223,7 @@ sub pagination_bar { =item output_with_http_headers - &output_with_http_headers($query, $cookie, $data, $content_type[, $status]) + &output_with_http_headers($query, $cookie, $data, $content_type[, $status[, $extra_options]]) Outputs $data with the appropriate HTTP headers, the authentication cookie $cookie and a Content-Type specified in @@ -265,12 +235,18 @@ $content_type is one of the following: 'html', 'js', 'json', 'xml', 'rss', or 'a $status is an HTTP status message, like '403 Authentication Required'. It defaults to '200 OK'. +$extra_options is hashref. If the key 'force_no_caching' is present and has +a true value, the HTTP headers include directives to force there to be no +caching whatsoever. + =cut -sub output_with_http_headers($$$$;$) { - my ( $query, $cookie, $data, $content_type, $status ) = @_; +sub output_with_http_headers { + my ( $query, $cookie, $data, $content_type, $status, $extra_options ) = @_; $status ||= '200 OK'; + $extra_options //= {}; + my %content_type_map = ( 'html' => 'text/html', 'js' => 'text/javascript', @@ -283,13 +259,18 @@ sub output_with_http_headers($$$$;$) { ); die "Unknown content type '$content_type'" if ( !defined( $content_type_map{$content_type} ) ); + my $cache_policy = 'no-cache'; + $cache_policy .= ', no-store, max-age=0' if $extra_options->{force_no_caching}; my $options = { - type => $content_type_map{$content_type}, - status => $status, - charset => 'UTF-8', - Pragma => 'no-cache', - 'Cache-Control' => 'no-cache', + type => $content_type_map{$content_type}, + status => $status, + charset => 'UTF-8', + Pragma => 'no-cache', + 'Cache-Control' => $cache_policy, + 'X-Frame-Options' => 'SAMEORIGIN', }; + $options->{expires} = 'now' if $extra_options->{force_no_caching}; + $options->{cookie} = $cookie if $cookie; if ($content_type eq 'html') { # guaranteed to be one of the content_type_map keys, else we'd have died $options->{'Content-Style-Type' } = 'text/css'; @@ -298,16 +279,14 @@ sub output_with_http_headers($$$$;$) { # We can't encode here, that will double encode our templates, and xslt # We need to fix the encoding as it comes out of the database, or when we pass the variables to templates - -# utf8::encode($data) if utf8::is_utf8($data); $data =~ s/\&\;amp\; /\&\; /g; print $query->header($options), $data; } -sub output_html_with_http_headers ($$$;$) { - my ( $query, $cookie, $data, $status ) = @_; - output_with_http_headers( $query, $cookie, $data, 'html', $status ); +sub output_html_with_http_headers { + my ( $query, $cookie, $data, $status, $extra_options ) = @_; + output_with_http_headers( $query, $cookie, $data, 'html', $status, $extra_options ); } @@ -327,6 +306,69 @@ sub is_ajax { return ( $x_req and $x_req =~ /XMLHttpRequest/i ) ? 1 : 0; } +=item output_and_exit_if_error + + output_and_exit_if_error( $query, $cookie, $template, $params ); + +To executed at the beginning of scripts to stop the script at this point if +some errors are found. + +Tests for module 'members': +* patron is not defined (we are looking for a patron that does no longer exist/never existed) +* The logged in user cannot see patron's infos (feature 'cannot_see_patron_infos') + +Others will be added here depending on the needs (for instance biblio does not exist will be useful). + +=cut + +sub output_and_exit_if_error { + my ( $query, $cookie, $template, $params ) = @_; + my $error; + if ( $params and exists $params->{module} ) { + if ( $params->{module} eq 'members' ) { + my $logged_in_user = $params->{logged_in_user}; + my $current_patron = $params->{current_patron}; + if ( not $current_patron ) { + $error = 'unknown_patron'; + } + elsif( not $logged_in_user->can_see_patron_infos( $current_patron ) ) { + $error = 'cannot_see_patron_infos'; + } + } + } + + output_and_exit( $query, $cookie, $template, $error ) if $error; + return; +} + +=item output_and_exit + + output_and_exit( $query, $cookie, $template, $error ); + + $error is a blocking error like biblionumber not found or so. + We should output the error and exit. + +=cut + +sub output_and_exit { + my ( $query, $cookie, $template, $error ) = @_; + $template->param( blocking_error => $error ); + output_html_with_http_headers ( $query, $cookie, $template->output ); + exit; +} + +sub parametrized_url { + my $url = shift || ''; # ie page.pl?ln={LANG} + my $vars = shift || {}; # ie { LANG => en } + my $ret = $url; + while ( my ($key,$val) = each %$vars) { + my $val_url = URI::Escape::uri_escape_utf8( $val // q{} ); + $ret =~ s/\{$key\}/$val_url/g; + } + $ret =~ s/\{[^\{]*\}//g; # remove remaining vars + return $ret; +} + END { } # module clean-up code here (global destructor) 1;