#!/usr/bin/perl -wT # The contents of this file are subject to the Mozilla Public # License Version 1.1 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or # implied. See the License for the specific language governing # rights and limitations under the License. # # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is Netscape Communications # Corporation. Portions created by Netscape are # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # # Contributor(s): Gervase Markham # use strict; use lib qw(. lib); use Bugzilla; use Bugzilla::Constants; use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::Field; use Bugzilla::Search; use Bugzilla::Report; use Bugzilla::Token; my $ARGS = Bugzilla->input_params; my $template = Bugzilla->template; my $vars = {}; # Go straight back to query.cgi if we are adding a boolean chart. if (grep /^cmd-/, keys %$ARGS) { $ARGS->{format} = $ARGS->{query_format}; delete $ARGS->{ctype}; print Bugzilla->cgi->redirect("query.cgi?" . http_build_query($ARGS)); exit; } Bugzilla->login(); my $dbh = Bugzilla->switch_to_shadow_db(); my $action = $ARGS->{action} || 'menu'; my $token = $ARGS->{token}; $vars->{measure_descs} = Bugzilla::Report->get_measures(); if ($action eq 'menu') { # No need to do any searching in this case, so bail out early. $template->process("reports/menu.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } elsif ($action eq 'add') { my $user = Bugzilla->login(LOGIN_REQUIRED); check_hash_token($token, ['save_report']); my $name = clean_text($ARGS->{name}); my $query = $ARGS->{query}; if (my ($report) = grep { lc($_->name) eq lc($name) } @{$user->reports}) { $report->set_query($query); $report->update; $vars->{message} = "report_updated"; } else { my $report = Bugzilla::Report->create({name => $name, query => $query}); $vars->{message} = "report_created"; } $user->flush_reports_cache; $vars->{reportname} = $name; $template->process("global/message.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } elsif ($action eq 'del') { my $user = Bugzilla->login(LOGIN_REQUIRED); my $report_id = $ARGS->{saved_report_id}; check_hash_token($token, ['delete_report', $report_id]); my $report = Bugzilla::Report->check({id => $report_id}); $report->remove_from_db(); $user->flush_reports_cache; $vars->{message} = 'report_deleted'; $vars->{reportname} = $report->name; $template->process("global/message.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } $vars->{time} = localtime(time()); $vars = { %$vars, %{Bugzilla::Report->execute($ARGS)} }; $vars->{saved_report_id} = $ARGS->{saved_report_id}; $vars->{debug} = $ARGS->{debug}; $vars->{report_columns} = Bugzilla::Search->REPORT_COLUMNS(); $ARGS->{ctype} = $ARGS->{action} eq 'plot' ? 'png' : ($ARGS->{format} eq 'csv' ? 'csv' : 'html'); $ARGS->{format} = $ARGS->{format} eq 'csv' ? 'table' : $ARGS->{format}; my $formatparam = $ARGS->{format}; if ($action eq 'wrap') { # So which template are we using? If action is "wrap", we will be using # no format (it gets passed through to be the format of the actual data), # and either report.csv.tmpl (CSV), or report.html.tmpl (everything else). # report.html.tmpl produces an HTML framework for either tables of HTML # data, or images generated by calling report.cgi again with action as # "plot". $formatparam =~ s/[^a-zA-Z\-]//g; trick_taint($formatparam); $vars->{format} = $formatparam; $formatparam = '' if $formatparam ne 'simple'; my $a = { %$ARGS }; delete $a->{$_} for $vars->{fields}->{z}, qw(action ctype format width height); $vars->{imagebase} = http_build_query($a); $a = { %$ARGS }; delete $a->{$_} for qw(query_format action ctype format width height measure); for (keys %$a) { delete $a->{$_} if $a->{$_} eq ''; } $vars->{switchparams} = $a; $vars->{switchbase} = http_build_query($a); } elsif ($action eq "plot") { # If action is "plot", we will be using a format as normal (pie, bar etc.) # and a ctype as normal (currently only png.) } else { ThrowCodeError("unknown_action", {action => $ARGS->{action}}); } my $format = $template->get_format("reports/report", $formatparam, $ARGS->{ctype}); # If we get a template or CGI error, it comes out as HTML, which isn't valid # PNG data, and the browser just displays a "corrupt PNG" message. So, you can # set debug=1 to always get an HTML content-type, and view the error. $format->{ctype} = "text/html" if $ARGS->{debug}; my @time = localtime(time()); my $date = sprintf "%04d-%02d-%02d", 1900+$time[5],$time[4]+1,$time[3]; my $filename = "report-$date.$format->{extension}"; Bugzilla->cgi->send_header( -type => $format->{ctype}, -content_disposition => "inline; filename=$filename", ); # Problems with this CGI are often due to malformed data. Setting debug=1 # prints out both data structures. if ($ARGS->{debug}) { require Data::Dumper; print "
data hash:\n";
    print html_quote(Data::Dumper::Dumper($vars->{data})) . "\n\n";
    print "data array:\n";
    print html_quote(Data::Dumper::Dumper($vars->{image_data})) . "\n\n
"; } # All formats point to the same section of the documentation. $vars->{doc_section} = 'reporting.html#reports'; disable_utf8() if ($format->{ctype} =~ /^image\//); $template->process($format->{template}, $vars) || ThrowTemplateError($template->error()); exit;