| Filename | /mnt/catalyst/koha/C4/Output.pm |
| Statements | Executed 36 statements in 5.47ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 4.68ms | 5.64ms | C4::Output::BEGIN@35 |
| 1 | 1 | 1 | 1.72ms | 1.72ms | C4::Output::CORE:print (opcode) |
| 1 | 1 | 1 | 411µs | 428µs | C4::Output::BEGIN@28 |
| 1 | 1 | 1 | 45µs | 3.17ms | C4::Output::output_with_http_headers |
| 1 | 1 | 1 | 21µs | 43µs | C4::Output::BEGIN@34 |
| 1 | 1 | 1 | 16µs | 16µs | C4::Output::BEGIN@40 |
| 1 | 1 | 1 | 11µs | 16µs | C4::Output::BEGIN@36 |
| 1 | 1 | 1 | 10µs | 47µs | C4::Output::BEGIN@31 |
| 1 | 1 | 1 | 8µs | 11µs | C4::Output::BEGIN@33 |
| 1 | 1 | 1 | 7µs | 56µs | C4::Output::BEGIN@38 |
| 1 | 1 | 1 | 4µs | 4µs | C4::Output::CORE:subst (opcode) |
| 1 | 1 | 1 | 2µs | 2µs | C4::Output::END |
| 0 | 0 | 0 | 0s | 0s | C4::Output::FormatData |
| 0 | 0 | 0 | 0s | 0s | C4::Output::FormatNumber |
| 0 | 0 | 0 | 0s | 0s | C4::Output::is_ajax |
| 0 | 0 | 0 | 0s | 0s | C4::Output::output_ajax_with_http_headers |
| 0 | 0 | 0 | 0s | 0s | C4::Output::output_html_with_http_headers |
| 0 | 0 | 0 | 0s | 0s | C4::Output::pagination_bar |
| 0 | 0 | 0 | 0s | 0s | C4::Output::parametrized_url |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package C4::Output; | ||||
| 2 | |||||
| 3 | #package to deal with marking up output | ||||
| 4 | #You will need to edit parts of this pm | ||||
| 5 | #set the value of path to be where your html lives | ||||
| 6 | |||||
| 7 | # Copyright 2000-2002 Katipo Communications | ||||
| 8 | # | ||||
| 9 | # This file is part of Koha. | ||||
| 10 | # | ||||
| 11 | # Koha is free software; you can redistribute it and/or modify it under the | ||||
| 12 | # terms of the GNU General Public License as published by the Free Software | ||||
| 13 | # Foundation; either version 2 of the License, or (at your option) any later | ||||
| 14 | # version. | ||||
| 15 | # | ||||
| 16 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | ||||
| 17 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||||
| 18 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||||
| 19 | # | ||||
| 20 | # You should have received a copy of the GNU General Public License along | ||||
| 21 | # with Koha; if not, write to the Free Software Foundation, Inc., | ||||
| 22 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| 23 | |||||
| 24 | |||||
| 25 | # NOTE: I'm pretty sure this module is deprecated in favor of | ||||
| 26 | # templates. | ||||
| 27 | |||||
| 28 | 2 | 31µs | 2 | 445µs | # spent 428µs (411+17) within C4::Output::BEGIN@28 which was called:
# once (411µs+17µs) by C4::Service::BEGIN@50 at line 28 # spent 428µs making 1 call to C4::Output::BEGIN@28
# spent 17µs making 1 call to strict::import |
| 29 | #use warnings; FIXME - Bug 2505 | ||||
| 30 | |||||
| 31 | 2 | 31µs | 2 | 85µs | # spent 47µs (10+37) within C4::Output::BEGIN@31 which was called:
# once (10µs+37µs) by C4::Service::BEGIN@50 at line 31 # spent 47µs making 1 call to C4::Output::BEGIN@31
# spent 37µs making 1 call to Exporter::import |
| 32 | |||||
| 33 | 2 | 22µs | 2 | 13µs | # spent 11µs (8+2) within C4::Output::BEGIN@33 which was called:
# once (8µs+2µs) by C4::Service::BEGIN@50 at line 33 # spent 11µs making 1 call to C4::Output::BEGIN@33
# spent 2µs making 1 call to C4::Context::import |
| 34 | 2 | 55µs | 2 | 65µs | # spent 43µs (21+22) within C4::Output::BEGIN@34 which was called:
# once (21µs+22µs) by C4::Service::BEGIN@50 at line 34 # spent 43µs making 1 call to C4::Output::BEGIN@34
# spent 22µs making 1 call to Exporter::import |
| 35 | 2 | 2.19ms | 2 | 5.74ms | # spent 5.64ms (4.68+960µs) within C4::Output::BEGIN@35 which was called:
# once (4.68ms+960µs) by C4::Service::BEGIN@50 at line 35 # spent 5.64ms making 1 call to C4::Output::BEGIN@35
# spent 101µs making 1 call to Exporter::import |
| 36 | 2 | 28µs | 2 | 22µs | # spent 16µs (11+5) within C4::Output::BEGIN@36 which was called:
# once (11µs+5µs) by C4::Service::BEGIN@50 at line 36 # spent 16µs making 1 call to C4::Output::BEGIN@36
# spent 5µs making 1 call to Class::Accessor::import |
| 37 | |||||
| 38 | 2 | 75µs | 2 | 106µs | # spent 56µs (7+50) within C4::Output::BEGIN@38 which was called:
# once (7µs+50µs) by C4::Service::BEGIN@50 at line 38 # spent 56µs making 1 call to C4::Output::BEGIN@38
# spent 50µs making 1 call to vars::import |
| 39 | |||||
| 40 | # spent 16µs within C4::Output::BEGIN@40 which was called:
# once (16µs+0s) by C4::Service::BEGIN@50 at line 59 | ||||
| 41 | # set the version for version checking | ||||
| 42 | 1 | 800ns | $VERSION = 3.07.00.049; | ||
| 43 | 1 | 500ns | require Exporter; | ||
| 44 | |||||
| 45 | 1 | 6µs | @ISA = qw(Exporter); | ||
| 46 | 1 | 400ns | @EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead | ||
| 47 | 1 | 4µs | %EXPORT_TAGS = ( all =>[qw(setlanguagecookie pagination_bar parametrized_url | ||
| 48 | &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)], | ||||
| 49 | ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)], | ||||
| 50 | html =>[qw(&output_with_http_headers &output_html_with_http_headers)] | ||||
| 51 | ); | ||||
| 52 | 1 | 700ns | push @EXPORT, qw( | ||
| 53 | setlanguagecookie getlanguagecookie pagination_bar parametrized_url | ||||
| 54 | ); | ||||
| 55 | 1 | 4µs | push @EXPORT, qw( | ||
| 56 | &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber | ||||
| 57 | ); | ||||
| 58 | |||||
| 59 | 1 | 1.26ms | 1 | 16µs | } # spent 16µs making 1 call to C4::Output::BEGIN@40 |
| 60 | |||||
| 61 | =head1 NAME | ||||
| 62 | |||||
| 63 | C4::Output - Functions for managing output, is slowly being deprecated | ||||
| 64 | |||||
| 65 | =head1 FUNCTIONS | ||||
| 66 | |||||
| 67 | =over 2 | ||||
| 68 | =cut | ||||
| 69 | |||||
| 70 | =item FormatNumber | ||||
| 71 | =cut | ||||
| 72 | sub FormatNumber{ | ||||
| 73 | my $cur = GetCurrency; | ||||
| 74 | my $cur_format = C4::Context->preference("CurrencyFormat"); | ||||
| 75 | my $num; | ||||
| 76 | |||||
| 77 | if ( $cur_format eq 'FR' ) { | ||||
| 78 | $num = new Number::Format( | ||||
| 79 | 'decimal_fill' => '2', | ||||
| 80 | 'decimal_point' => ',', | ||||
| 81 | 'int_curr_symbol' => $cur->{symbol}, | ||||
| 82 | 'mon_thousands_sep' => ' ', | ||||
| 83 | 'thousands_sep' => ' ', | ||||
| 84 | 'mon_decimal_point' => ',' | ||||
| 85 | ); | ||||
| 86 | } else { # US by default.. | ||||
| 87 | $num = new Number::Format( | ||||
| 88 | 'int_curr_symbol' => '', | ||||
| 89 | 'mon_thousands_sep' => ',', | ||||
| 90 | 'mon_decimal_point' => '.' | ||||
| 91 | ); | ||||
| 92 | } | ||||
| 93 | return $num; | ||||
| 94 | } | ||||
| 95 | |||||
| 96 | =item FormatData | ||||
| 97 | |||||
| 98 | FormatData($data_hashref) | ||||
| 99 | C<$data_hashref> is a ref to data to format | ||||
| 100 | |||||
| 101 | Format dates of data those dates are assumed to contain date in their noun | ||||
| 102 | Could be used in order to centralize all the formatting for HTML output | ||||
| 103 | =cut | ||||
| 104 | |||||
| 105 | sub FormatData{ | ||||
| 106 | my $data_hashref=shift; | ||||
| 107 | $$data_hashref{$_} = format_date( $$data_hashref{$_} ) for grep{/date/} keys (%$data_hashref); | ||||
| 108 | } | ||||
| 109 | |||||
| 110 | =item pagination_bar | ||||
| 111 | |||||
| 112 | pagination_bar($base_url, $nb_pages, $current_page, $startfrom_name) | ||||
| 113 | |||||
| 114 | Build an HTML pagination bar based on the number of page to display, the | ||||
| 115 | current page and the url to give to each page link. | ||||
| 116 | |||||
| 117 | C<$base_url> is the URL for each page link. The | ||||
| 118 | C<$startfrom_name>=page_number is added at the end of the each URL. | ||||
| 119 | |||||
| 120 | C<$nb_pages> is the total number of pages available. | ||||
| 121 | |||||
| 122 | C<$current_page> is the current page number. This page number won't become a | ||||
| 123 | link. | ||||
| 124 | |||||
| 125 | This function returns HTML, without any language dependency. | ||||
| 126 | |||||
| 127 | =cut | ||||
| 128 | |||||
| 129 | sub pagination_bar { | ||||
| 130 | my $base_url = (@_ ? shift : $ENV{SCRIPT_NAME} . $ENV{QUERY_STRING}) or return; | ||||
| 131 | my $nb_pages = (@_) ? shift : 1; | ||||
| 132 | my $current_page = (@_) ? shift : undef; # delay default until later | ||||
| 133 | my $startfrom_name = (@_) ? shift : 'page'; | ||||
| 134 | |||||
| 135 | # how many pages to show before and after the current page? | ||||
| 136 | my $pages_around = 2; | ||||
| 137 | |||||
| 138 | my $delim = qr/\&(?:amp;)?|;/; # "non memory" cluster: no backreference | ||||
| 139 | $base_url =~ s/$delim*\b$startfrom_name=(\d+)//g; # remove previous pagination var | ||||
| 140 | unless (defined $current_page and $current_page > 0 and $current_page <= $nb_pages) { | ||||
| 141 | $current_page = ($1) ? $1 : 1; # pull current page from param in URL, else default to 1 | ||||
| 142 | # $debug and # FIXME: use C4::Debug; | ||||
| 143 | # warn "with QUERY_STRING:" .$ENV{QUERY_STRING}. "\ncurrent_page:$current_page\n1:$1 2:$2 3:$3"; | ||||
| 144 | } | ||||
| 145 | $base_url =~ s/($delim)+/$1/g; # compress duplicate delims | ||||
| 146 | $base_url =~ s/$delim;//g; # remove empties | ||||
| 147 | $base_url =~ s/$delim$//; # remove trailing delim | ||||
| 148 | |||||
| 149 | my $url = $base_url . (($base_url =~ m/$delim/ or $base_url =~ m/\?/) ? '&' : '?' ) . $startfrom_name . '='; | ||||
| 150 | my $pagination_bar = ''; | ||||
| 151 | |||||
| 152 | # navigation bar useful only if more than one page to display ! | ||||
| 153 | if ( $nb_pages > 1 ) { | ||||
| 154 | |||||
| 155 | # link to first page? | ||||
| 156 | if ( $current_page > 1 ) { | ||||
| 157 | $pagination_bar .= | ||||
| 158 | "\n" . ' ' | ||||
| 159 | . '<a href="' | ||||
| 160 | . $url | ||||
| 161 | . '1" rel="start">' | ||||
| 162 | . '<<' . '</a>'; | ||||
| 163 | } | ||||
| 164 | else { | ||||
| 165 | $pagination_bar .= | ||||
| 166 | "\n" . ' <span class="inactive"><<</span>'; | ||||
| 167 | } | ||||
| 168 | |||||
| 169 | # link on previous page ? | ||||
| 170 | if ( $current_page > 1 ) { | ||||
| 171 | my $previous = $current_page - 1; | ||||
| 172 | |||||
| 173 | $pagination_bar .= | ||||
| 174 | "\n" . ' ' | ||||
| 175 | . '<a href="' | ||||
| 176 | . $url | ||||
| 177 | . $previous | ||||
| 178 | . '" rel="prev">' . '<' . '</a>'; | ||||
| 179 | } | ||||
| 180 | else { | ||||
| 181 | $pagination_bar .= | ||||
| 182 | "\n" . ' <span class="inactive"><</span>'; | ||||
| 183 | } | ||||
| 184 | |||||
| 185 | my $min_to_display = $current_page - $pages_around; | ||||
| 186 | my $max_to_display = $current_page + $pages_around; | ||||
| 187 | my $last_displayed_page = undef; | ||||
| 188 | |||||
| 189 | for my $page_number ( 1 .. $nb_pages ) { | ||||
| 190 | if ( | ||||
| 191 | $page_number == 1 | ||||
| 192 | or $page_number == $nb_pages | ||||
| 193 | or ( $page_number >= $min_to_display | ||||
| 194 | and $page_number <= $max_to_display ) | ||||
| 195 | ) | ||||
| 196 | { | ||||
| 197 | if ( defined $last_displayed_page | ||||
| 198 | and $last_displayed_page != $page_number - 1 ) | ||||
| 199 | { | ||||
| 200 | $pagination_bar .= | ||||
| 201 | "\n" . ' <span class="inactive">...</span>'; | ||||
| 202 | } | ||||
| 203 | |||||
| 204 | if ( $page_number == $current_page ) { | ||||
| 205 | $pagination_bar .= | ||||
| 206 | "\n" . ' ' | ||||
| 207 | . '<span class="currentPage">' | ||||
| 208 | . $page_number | ||||
| 209 | . '</span>'; | ||||
| 210 | } | ||||
| 211 | else { | ||||
| 212 | $pagination_bar .= | ||||
| 213 | "\n" . ' ' | ||||
| 214 | . '<a href="' | ||||
| 215 | . $url | ||||
| 216 | . $page_number . '">' | ||||
| 217 | . $page_number . '</a>'; | ||||
| 218 | } | ||||
| 219 | $last_displayed_page = $page_number; | ||||
| 220 | } | ||||
| 221 | } | ||||
| 222 | |||||
| 223 | # link on next page? | ||||
| 224 | if ( $current_page < $nb_pages ) { | ||||
| 225 | my $next = $current_page + 1; | ||||
| 226 | |||||
| 227 | $pagination_bar .= "\n" | ||||
| 228 | . ' <a href="' | ||||
| 229 | . $url | ||||
| 230 | . $next | ||||
| 231 | . '" rel="next">' . '>' . '</a>'; | ||||
| 232 | } | ||||
| 233 | else { | ||||
| 234 | $pagination_bar .= | ||||
| 235 | "\n" . ' <span class="inactive">></span>'; | ||||
| 236 | } | ||||
| 237 | |||||
| 238 | # link to last page? | ||||
| 239 | if ( $current_page != $nb_pages ) { | ||||
| 240 | $pagination_bar .= "\n" | ||||
| 241 | . ' <a href="' | ||||
| 242 | . $url | ||||
| 243 | . $nb_pages | ||||
| 244 | . '" rel="last">' | ||||
| 245 | . '>>' . '</a>'; | ||||
| 246 | } | ||||
| 247 | else { | ||||
| 248 | $pagination_bar .= | ||||
| 249 | "\n" . ' <span class="inactive">>></span>'; | ||||
| 250 | } | ||||
| 251 | } | ||||
| 252 | |||||
| 253 | return $pagination_bar; | ||||
| 254 | } | ||||
| 255 | |||||
| 256 | =item output_with_http_headers | ||||
| 257 | |||||
| 258 | &output_with_http_headers($query, $cookie, $data, $content_type[, $status[, $extra_options]]) | ||||
| 259 | |||||
| 260 | Outputs $data with the appropriate HTTP headers, | ||||
| 261 | the authentication cookie $cookie and a Content-Type specified in | ||||
| 262 | $content_type. | ||||
| 263 | |||||
| 264 | If applicable, $cookie can be undef, and it will not be sent. | ||||
| 265 | |||||
| 266 | $content_type is one of the following: 'html', 'js', 'json', 'xml', 'rss', or 'atom'. | ||||
| 267 | |||||
| 268 | $status is an HTTP status message, like '403 Authentication Required'. It defaults to '200 OK'. | ||||
| 269 | |||||
| 270 | $extra_options is hashref. If the key 'force_no_caching' is present and has | ||||
| 271 | a true value, the HTTP headers include directives to force there to be no | ||||
| 272 | caching whatsoever. | ||||
| 273 | |||||
| 274 | =cut | ||||
| 275 | |||||
| 276 | # spent 3.17ms (45µs+3.12) within C4::Output::output_with_http_headers which was called:
# once (45µs+3.12ms) by C4::Service::return_error at line 130 of C4/Service.pm | ||||
| 277 | 1 | 900ns | my ( $query, $cookie, $data, $content_type, $status, $extra_options ) = @_; | ||
| 278 | 1 | 300ns | $status ||= '200 OK'; | ||
| 279 | |||||
| 280 | 1 | 400ns | $extra_options //= {}; | ||
| 281 | |||||
| 282 | 1 | 4µs | my %content_type_map = ( | ||
| 283 | 'html' => 'text/html', | ||||
| 284 | 'js' => 'text/javascript', | ||||
| 285 | 'json' => 'application/json', | ||||
| 286 | 'xml' => 'text/xml', | ||||
| 287 | # NOTE: not using application/atom+xml or application/rss+xml because of | ||||
| 288 | # Internet Explorer 6; see bug 2078. | ||||
| 289 | 'rss' => 'text/xml', | ||||
| 290 | 'atom' => 'text/xml' | ||||
| 291 | ); | ||||
| 292 | |||||
| 293 | 1 | 600ns | die "Unknown content type '$content_type'" if ( !defined( $content_type_map{$content_type} ) ); | ||
| 294 | 1 | 300ns | my $cache_policy = 'no-cache'; | ||
| 295 | 1 | 400ns | $cache_policy .= ', no-store, max-age=0' if $extra_options->{force_no_caching}; | ||
| 296 | 1 | 3µs | my $options = { | ||
| 297 | type => $content_type_map{$content_type}, | ||||
| 298 | status => $status, | ||||
| 299 | charset => 'UTF-8', | ||||
| 300 | Pragma => 'no-cache', | ||||
| 301 | 'Cache-Control' => $cache_policy, | ||||
| 302 | }; | ||||
| 303 | 1 | 400ns | $options->{expires} = 'now' if $extra_options->{force_no_caching}; | ||
| 304 | |||||
| 305 | 1 | 5µs | 1 | 81µs | $options->{cookie} = $cookie if $cookie; # spent 81µs making 1 call to CGI::Cookie::as_string |
| 306 | 1 | 400ns | if ($content_type eq 'html') { # guaranteed to be one of the content_type_map keys, else we'd have died | ||
| 307 | $options->{'Content-Style-Type' } = 'text/css'; | ||||
| 308 | $options->{'Content-Script-Type'} = 'text/javascript'; | ||||
| 309 | } | ||||
| 310 | |||||
| 311 | # We can't encode here, that will double encode our templates, and xslt | ||||
| 312 | # We need to fix the encoding as it comes out of the database, or when we pass the variables to templates | ||||
| 313 | |||||
| 314 | # utf8::encode($data) if utf8::is_utf8($data); | ||||
| 315 | |||||
| 316 | 1 | 7µs | 1 | 4µs | $data =~ s/\&\;amp\; /\&\; /g; # spent 4µs making 1 call to C4::Output::CORE:subst |
| 317 | 1 | 1.74ms | 2 | 2.34ms | print $query->header($options), $data; # spent 1.72ms making 1 call to C4::Output::CORE:print
# spent 618µs making 1 call to CGI::AUTOLOAD |
| 318 | } | ||||
| 319 | |||||
| 320 | sub output_html_with_http_headers { | ||||
| 321 | my ( $query, $cookie, $data, $status, $extra_options ) = @_; | ||||
| 322 | output_with_http_headers( $query, $cookie, $data, 'html', $status, $extra_options ); | ||||
| 323 | } | ||||
| 324 | |||||
| 325 | |||||
| 326 | sub output_ajax_with_http_headers { | ||||
| 327 | my ( $query, $js ) = @_; | ||||
| 328 | print $query->header( | ||||
| 329 | -type => 'text/javascript', | ||||
| 330 | -charset => 'UTF-8', | ||||
| 331 | -Pragma => 'no-cache', | ||||
| 332 | -'Cache-Control' => 'no-cache', | ||||
| 333 | -expires => '-1d', | ||||
| 334 | ), $js; | ||||
| 335 | } | ||||
| 336 | |||||
| 337 | sub is_ajax { | ||||
| 338 | my $x_req = $ENV{HTTP_X_REQUESTED_WITH}; | ||||
| 339 | return ( $x_req and $x_req =~ /XMLHttpRequest/i ) ? 1 : 0; | ||||
| 340 | } | ||||
| 341 | |||||
| 342 | sub parametrized_url { | ||||
| 343 | my $url = shift || ''; # ie page.pl?ln={LANG} | ||||
| 344 | my $vars = shift || {}; # ie { LANG => en } | ||||
| 345 | my $ret = $url; | ||||
| 346 | while ( my ($key,$val) = each %$vars) { | ||||
| 347 | my $val_url = URI::Escape::uri_escape_utf8($val); | ||||
| 348 | $ret =~ s/\{$key\}/$val_url/g; | ||||
| 349 | } | ||||
| 350 | $ret =~ s/\{[^\{]*\}//g; # remove not defined vars | ||||
| 351 | return $ret; | ||||
| 352 | } | ||||
| 353 | |||||
| 354 | 1 | 3µs | # spent 2µs within C4::Output::END which was called:
# once (2µs+0s) by main::RUNTIME at line 131 of C4/Service.pm | ||
| 355 | |||||
| 356 | 1 | 3µs | 1; | ||
| 357 | __END__ | ||||
# spent 1.72ms within C4::Output::CORE:print which was called:
# once (1.72ms+0s) by C4::Output::output_with_http_headers at line 317 | |||||
# spent 4µs within C4::Output::CORE:subst which was called:
# once (4µs+0s) by C4::Output::output_with_http_headers at line 316 |