diff options
author | bbaetz%student.usyd.edu.au <> | 2002-12-15 18:23:55 +0100 |
---|---|---|
committer | bbaetz%student.usyd.edu.au <> | 2002-12-15 18:23:55 +0100 |
commit | 1cee4770ca5e09e3b56c0de0e8c77c2684542d18 (patch) | |
tree | a31b3c625607961094750db3f7619619a9d7767f | |
parent | ee84183ca9efa0839c49ad02f293d60db0a4d76f (diff) | |
download | bugzilla-1cee4770ca5e09e3b56c0de0e8c77c2684542d18.tar.gz bugzilla-1cee4770ca5e09e3b56c0de0e8c77c2684542d18.tar.xz |
Bug 158499 - Templatise XML bug output
r=gerv, justdave
a=justdave
-rwxr-xr-x | Bug.pm | 158 | ||||
-rwxr-xr-x | Bugzilla/Bug.pm | 158 | ||||
-rw-r--r-- | Bugzilla/Util.pm | 27 | ||||
-rw-r--r-- | bugzilla.dtd | 8 | ||||
-rwxr-xr-x | checksetup.pl | 3 | ||||
-rw-r--r-- | globals.pl | 2 | ||||
-rwxr-xr-x | move.pl | 16 | ||||
-rwxr-xr-x | show_bug.cgi | 42 | ||||
-rw-r--r-- | t/004template.t | 1 | ||||
-rw-r--r-- | template/en/default/bug/choose-xml.html.tmpl | 51 | ||||
-rw-r--r-- | template/en/default/bug/choose.html.tmpl | 8 | ||||
-rw-r--r-- | template/en/default/bug/show.html.tmpl | 3 | ||||
-rw-r--r-- | template/en/default/bug/show.xml.tmpl | 84 | ||||
-rwxr-xr-x | xml.cgi | 29 |
14 files changed, 230 insertions, 360 deletions
@@ -32,7 +32,6 @@ use vars qw($unconfirmedstate $legal_keywords @legal_platform @enterable_products %milestoneurl %prodmaxvotes); use CGI::Carp qw(fatalsToBrowser); -my %ok_field; use Attachment; use Bugzilla::Config; @@ -42,18 +41,33 @@ use Bugzilla::FlagType; use Bugzilla::User; use Bugzilla::Util; -for my $key (qw (bug_id alias product version rep_platform op_sys bug_status - resolution priority bug_severity component assigned_to - reporter bug_file_loc short_desc target_milestone - qa_contact status_whiteboard creation_ts keywords - delta_ts votes whoid usergroupset comment query error - longdescs cc milestoneurl attachments dependson blocked - cclist_accessible reporter_accessible - isopened isunconfirmed assigned_to_name assigned_to_email - qa_contact_name qa_contact_email reporter_name - reporter_email flag_types num_attachment_flag_types - show_attachment_flags use_keywords any_flags_requesteeble - estimated_time remaining_time actual_time) ) { +sub fields { + # Keep this ordering in sync with bugzilla.dtd + my @fields = qw(bug_id alias creation_ts short_desc delta_ts + reporter_accessible cclist_accessible + product component version rep_platform op_sys + bug_status resolution + bug_file_loc status_whiteboard keywords + priority bug_severity target_milestone + dependson blocked votes + reporter assigned_to qa_contact cc + ); + + if (Param('timetrackinggroup')) { + push @fields, qw(estimated_time remaining_time actual_time); + } + + return @fields; +} + +my %ok_field; +foreach my $key (qw(error groups + longdescs milestoneurl attachments + isopened isunconfirmed + flag_types num_attachment_flag_types + show_attachment_flags use_keywords any_flags_requesteeble + ), + fields()) { $ok_field{$key}++; } @@ -81,8 +95,6 @@ sub new { return $self; } - - # dump info about bug into hash unless user doesn't have permission # user_id 0 is used when person is not logged in. # @@ -90,10 +102,13 @@ sub initBug { my $self = shift(); my ($bug_id, $user_id) = (@_); + $bug_id = trim($bug_id); + + my $old_bug_id = $bug_id; + # If the bug ID isn't numeric, it might be an alias, so try to convert it. $bug_id = &::BugAliasToID($bug_id) if $bug_id !~ /^[1-9][0-9]*$/; - - my $old_bug_id = $bug_id; + if ((! defined $bug_id) || (!$bug_id) || (!detaint_natural($bug_id))) { # no bug number given or the alias didn't match a bug $self->{'bug_id'} = $old_bug_id; @@ -232,7 +247,7 @@ sub initBug { my @depends = EmitDependList("blocked", "dependson", $bug_id); if (@depends) { $self->{'dependson'} = \@depends; - } + } my @blocked = EmitDependList("dependson", "blocked", $bug_id); if (@blocked) { $self->{'blocked'} = \@blocked; @@ -327,6 +342,7 @@ sub groups { && ($membercontrol == CONTROLMAPMANDATORY); push (@groups, { "bit" => $groupid, + "name" => $name, "ison" => $ison, "ingroup" => $ingroup, "mandatory" => $ismandatory, @@ -427,77 +443,6 @@ sub choices { return $self->{'choices'}; } -# given a bug hash, emit xml for it. with file header provided by caller -# -sub emitXML { - ( $#_ == 0 ) || confess("invalid number of arguments"); - my $self = shift(); - my $xml; - - - if (exists $self->{'error'}) { - $xml .= "<bug error=\"$self->{'error'}\">\n"; - $xml .= " <bug_id>$self->{'bug_id'}</bug_id>\n"; - $xml .= "</bug>\n"; - return $xml; - } - - $xml .= "<bug>\n"; - - foreach my $field ("bug_id", "alias", "bug_status", "product", - "priority", "version", "rep_platform", "assigned_to", "delta_ts", - "component", "reporter", "target_milestone", "bug_severity", - "creation_ts", "qa_contact", "op_sys", "resolution", "bug_file_loc", - "short_desc", "keywords", "status_whiteboard") { - if ($self->{$field}) { - $xml .= " <$field>" . QuoteXMLChars($self->{$field}) . "</$field>\n"; - } - } - - foreach my $field ("dependson", "blocked", "cc") { - if (defined $self->{$field}) { - for (my $i=0 ; $i < @{$self->{$field}} ; $i++) { - $xml .= " <$field>" . $self->{$field}[$i] . "</$field>\n"; - } - } - } - - if (defined $self->{'longdescs'}) { - for (my $i=0 ; $i < @{$self->{'longdescs'}} ; $i++) { - next if ($self->{'longdescs'}[$i]->{'isprivate'} - && Param("insidergroup") - && !&::UserInGroup(Param("insidergroup"))); - $xml .= " <long_desc>\n"; - $xml .= " <who>" . $self->{'longdescs'}[$i]->{'email'} - . "</who>\n"; - $xml .= " <bug_when>" . $self->{'longdescs'}[$i]->{'time'} - . "</bug_when>\n"; - $xml .= " <thetext>" . QuoteXMLChars($self->{'longdescs'}[$i]->{'body'}) - . "</thetext>\n"; - $xml .= " </long_desc>\n"; - } - } - - if (defined $self->{'attachments'}) { - for (my $i=0 ; $i < @{$self->{'attachments'}} ; $i++) { - next if ($self->{'attachments'}[$i]->{'isprivate'} - && Param("insidergroup") - && !&::UserInGroup(Param("insidergroup"))); - $xml .= " <attachment>\n"; - $xml .= " <attachid>" . $self->{'attachments'}[$i]->{'attachid'} - . "</attachid>\n"; - $xml .= " <date>" . $self->{'attachments'}[$i]->{'date'} . "</date>\n"; - $xml .= " <desc>" . QuoteXMLChars($self->{'attachments'}[$i]->{'description'}) . "</desc>\n"; - # $xml .= " <type>" . $self->{'attachments'}[$i]->{'type'} . "</type>\n"; - # $xml .= " <data>" . $self->{'attachments'}[$i]->{'data'} . "</data>\n"; - $xml .= " </attachment>\n"; - } - } - - $xml .= "</bug>\n"; - return $xml; -} - sub EmitDependList { my ($myfield, $targetfield, $bug_id) = (@_); my @list; @@ -513,41 +458,6 @@ sub EmitDependList { return @list; } -sub QuoteXMLChars { - $_[0] =~ s/&/&/g; - $_[0] =~ s/</</g; - $_[0] =~ s/>/>/g; - $_[0] =~ s/\'/'/g; - $_[0] =~ s/\"/"/g; -# $_[0] =~ s/([\x80-\xFF])/&XmlUtf8Encode(ord($1))/ge; - return($_[0]); -} - -sub XML_Header { - my ($urlbase, $version, $maintainer, $exporter) = (@_); - - my $xml; - $xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\n"; - $xml .= "<!DOCTYPE bugzilla SYSTEM \"$urlbase"; - if (! ($urlbase =~ /.+\/$/)) { - $xml .= "/"; - } - $xml .= "bugzilla.dtd\">\n"; - $xml .= "<bugzilla"; - if (defined $exporter) { - $xml .= " exporter=\"$exporter\""; - } - $xml .= " version=\"$version\""; - $xml .= " urlbase=\"$urlbase\""; - $xml .= " maintainer=\"$maintainer\">\n"; - return ($xml); -} - - -sub XML_Footer { - return ("</bugzilla>\n"); -} - sub AUTOLOAD { use vars qw($AUTOLOAD); my $attr = $AUTOLOAD; diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm index 7d7a1debc..251ad16e2 100755 --- a/Bugzilla/Bug.pm +++ b/Bugzilla/Bug.pm @@ -32,7 +32,6 @@ use vars qw($unconfirmedstate $legal_keywords @legal_platform @enterable_products %milestoneurl %prodmaxvotes); use CGI::Carp qw(fatalsToBrowser); -my %ok_field; use Attachment; use Bugzilla::Config; @@ -42,18 +41,33 @@ use Bugzilla::FlagType; use Bugzilla::User; use Bugzilla::Util; -for my $key (qw (bug_id alias product version rep_platform op_sys bug_status - resolution priority bug_severity component assigned_to - reporter bug_file_loc short_desc target_milestone - qa_contact status_whiteboard creation_ts keywords - delta_ts votes whoid usergroupset comment query error - longdescs cc milestoneurl attachments dependson blocked - cclist_accessible reporter_accessible - isopened isunconfirmed assigned_to_name assigned_to_email - qa_contact_name qa_contact_email reporter_name - reporter_email flag_types num_attachment_flag_types - show_attachment_flags use_keywords any_flags_requesteeble - estimated_time remaining_time actual_time) ) { +sub fields { + # Keep this ordering in sync with bugzilla.dtd + my @fields = qw(bug_id alias creation_ts short_desc delta_ts + reporter_accessible cclist_accessible + product component version rep_platform op_sys + bug_status resolution + bug_file_loc status_whiteboard keywords + priority bug_severity target_milestone + dependson blocked votes + reporter assigned_to qa_contact cc + ); + + if (Param('timetrackinggroup')) { + push @fields, qw(estimated_time remaining_time actual_time); + } + + return @fields; +} + +my %ok_field; +foreach my $key (qw(error groups + longdescs milestoneurl attachments + isopened isunconfirmed + flag_types num_attachment_flag_types + show_attachment_flags use_keywords any_flags_requesteeble + ), + fields()) { $ok_field{$key}++; } @@ -81,8 +95,6 @@ sub new { return $self; } - - # dump info about bug into hash unless user doesn't have permission # user_id 0 is used when person is not logged in. # @@ -90,10 +102,13 @@ sub initBug { my $self = shift(); my ($bug_id, $user_id) = (@_); + $bug_id = trim($bug_id); + + my $old_bug_id = $bug_id; + # If the bug ID isn't numeric, it might be an alias, so try to convert it. $bug_id = &::BugAliasToID($bug_id) if $bug_id !~ /^[1-9][0-9]*$/; - - my $old_bug_id = $bug_id; + if ((! defined $bug_id) || (!$bug_id) || (!detaint_natural($bug_id))) { # no bug number given or the alias didn't match a bug $self->{'bug_id'} = $old_bug_id; @@ -232,7 +247,7 @@ sub initBug { my @depends = EmitDependList("blocked", "dependson", $bug_id); if (@depends) { $self->{'dependson'} = \@depends; - } + } my @blocked = EmitDependList("dependson", "blocked", $bug_id); if (@blocked) { $self->{'blocked'} = \@blocked; @@ -327,6 +342,7 @@ sub groups { && ($membercontrol == CONTROLMAPMANDATORY); push (@groups, { "bit" => $groupid, + "name" => $name, "ison" => $ison, "ingroup" => $ingroup, "mandatory" => $ismandatory, @@ -427,77 +443,6 @@ sub choices { return $self->{'choices'}; } -# given a bug hash, emit xml for it. with file header provided by caller -# -sub emitXML { - ( $#_ == 0 ) || confess("invalid number of arguments"); - my $self = shift(); - my $xml; - - - if (exists $self->{'error'}) { - $xml .= "<bug error=\"$self->{'error'}\">\n"; - $xml .= " <bug_id>$self->{'bug_id'}</bug_id>\n"; - $xml .= "</bug>\n"; - return $xml; - } - - $xml .= "<bug>\n"; - - foreach my $field ("bug_id", "alias", "bug_status", "product", - "priority", "version", "rep_platform", "assigned_to", "delta_ts", - "component", "reporter", "target_milestone", "bug_severity", - "creation_ts", "qa_contact", "op_sys", "resolution", "bug_file_loc", - "short_desc", "keywords", "status_whiteboard") { - if ($self->{$field}) { - $xml .= " <$field>" . QuoteXMLChars($self->{$field}) . "</$field>\n"; - } - } - - foreach my $field ("dependson", "blocked", "cc") { - if (defined $self->{$field}) { - for (my $i=0 ; $i < @{$self->{$field}} ; $i++) { - $xml .= " <$field>" . $self->{$field}[$i] . "</$field>\n"; - } - } - } - - if (defined $self->{'longdescs'}) { - for (my $i=0 ; $i < @{$self->{'longdescs'}} ; $i++) { - next if ($self->{'longdescs'}[$i]->{'isprivate'} - && Param("insidergroup") - && !&::UserInGroup(Param("insidergroup"))); - $xml .= " <long_desc>\n"; - $xml .= " <who>" . $self->{'longdescs'}[$i]->{'email'} - . "</who>\n"; - $xml .= " <bug_when>" . $self->{'longdescs'}[$i]->{'time'} - . "</bug_when>\n"; - $xml .= " <thetext>" . QuoteXMLChars($self->{'longdescs'}[$i]->{'body'}) - . "</thetext>\n"; - $xml .= " </long_desc>\n"; - } - } - - if (defined $self->{'attachments'}) { - for (my $i=0 ; $i < @{$self->{'attachments'}} ; $i++) { - next if ($self->{'attachments'}[$i]->{'isprivate'} - && Param("insidergroup") - && !&::UserInGroup(Param("insidergroup"))); - $xml .= " <attachment>\n"; - $xml .= " <attachid>" . $self->{'attachments'}[$i]->{'attachid'} - . "</attachid>\n"; - $xml .= " <date>" . $self->{'attachments'}[$i]->{'date'} . "</date>\n"; - $xml .= " <desc>" . QuoteXMLChars($self->{'attachments'}[$i]->{'description'}) . "</desc>\n"; - # $xml .= " <type>" . $self->{'attachments'}[$i]->{'type'} . "</type>\n"; - # $xml .= " <data>" . $self->{'attachments'}[$i]->{'data'} . "</data>\n"; - $xml .= " </attachment>\n"; - } - } - - $xml .= "</bug>\n"; - return $xml; -} - sub EmitDependList { my ($myfield, $targetfield, $bug_id) = (@_); my @list; @@ -513,41 +458,6 @@ sub EmitDependList { return @list; } -sub QuoteXMLChars { - $_[0] =~ s/&/&/g; - $_[0] =~ s/</</g; - $_[0] =~ s/>/>/g; - $_[0] =~ s/\'/'/g; - $_[0] =~ s/\"/"/g; -# $_[0] =~ s/([\x80-\xFF])/&XmlUtf8Encode(ord($1))/ge; - return($_[0]); -} - -sub XML_Header { - my ($urlbase, $version, $maintainer, $exporter) = (@_); - - my $xml; - $xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\n"; - $xml .= "<!DOCTYPE bugzilla SYSTEM \"$urlbase"; - if (! ($urlbase =~ /.+\/$/)) { - $xml .= "/"; - } - $xml .= "bugzilla.dtd\">\n"; - $xml .= "<bugzilla"; - if (defined $exporter) { - $xml .= " exporter=\"$exporter\""; - } - $xml .= " version=\"$version\""; - $xml .= " urlbase=\"$urlbase\""; - $xml .= " maintainer=\"$maintainer\">\n"; - return ($xml); -} - - -sub XML_Footer { - return ("</bugzilla>\n"); -} - sub AUTOLOAD { use vars qw($AUTOLOAD); my $attr = $AUTOLOAD; diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm index efd107c0a..5aecb5ad9 100644 --- a/Bugzilla/Util.pm +++ b/Bugzilla/Util.pm @@ -25,15 +25,15 @@ package Bugzilla::Util; -use Bugzilla::Config; +use strict; use base qw(Exporter); @Bugzilla::Util::EXPORT = qw(is_tainted trick_taint detaint_natural - html_quote url_quote value_quote + html_quote url_quote value_quote xml_quote lsearch max min trim format_time); -use strict; +use Bugzilla::Config; # This is from the perlsec page, slightly modifed to remove a warning # From that page: @@ -89,6 +89,16 @@ sub value_quote { return $var; } +sub xml_quote { + my ($var) = (@_); + $var =~ s/\&/\&/g; + $var =~ s/</\</g; + $var =~ s/>/\>/g; + $var =~ s/\"/\"/g; + $var =~ s/\'/\'/g; + return $var; +} + sub lsearch { my ($list,$item) = (@_); my $count = 0; @@ -124,7 +134,6 @@ sub trim { return $str; } -# Bug 67077 sub format_time { my ($time) = @_; @@ -149,7 +158,8 @@ sub format_time { } if (defined $year) { - $time = "$year-$month-$day $hour:$min " . &::Param('timezone'); + $time = "$year-$month-$day $hour:$min"; + $time .= " " . &::Param('timezone') if &::Param('timezone'); } return $time; } @@ -175,6 +185,7 @@ Bugzilla::Util - Generic utility functions for bugzilla html_quote($var); url_quote($var); value_quote($var); + xml_quote($var); # Functions for searching $loc = lsearch(\@arr, $val); @@ -252,6 +263,12 @@ Quotes characters so that they may be included as part of a url. As well as escaping html like C<html_quote>, this routine converts newlines into 
, suitable for use in html attributes. +=item C<xml_quote($val)> + +This is similar to C<html_quote>, except that ' is escaped to '. This +is kept separate from html_quote partly for compatibility with previous code +(for ') and partly for future handling of non-ASCII characters. + =back =head2 Searching diff --git a/bugzilla.dtd b/bugzilla.dtd index 0445d0a4e..aecf9920d 100644 --- a/bugzilla.dtd +++ b/bugzilla.dtd @@ -5,12 +5,14 @@ maintainer CDATA #REQUIRED exporter CDATA #IMPLIED > -<!ELEMENT bug (bug_id, (alias?, bug_status, product, priority, version, rep_platform, assigned_to, delta_ts, component, reporter, target_milestone?, bug_severity, creation_ts, qa_contact?, op_sys, resolution?, bug_file_loc?, short_desc?, keywords*, status_whiteboard?, dependson*, blocked*, cc*, long_desc*, attachment*)?)> +<!ELEMENT bug (bug_id, (alias?, creation_ts, short_desc, delta_ts, reporter_accessible, cclist_accessible, product, component, version, rep_platform, op_sys, bug_status, resolution?, bug_file_loc?, status_whiteboard?, keywords*, priority, bug_severity, target_milestone?, dependson*, blocked*, votes?, reporter, assigned_to, qa_contact?, cc*, (estimated_time, remaining_time, actual_time)?, groups*, long_desc*, attachment*)?)> <!ATTLIST bug error (NotFound | NotPermitted | InvalidBugId) #IMPLIED > <!ELEMENT bug_id (#PCDATA)> <!ELEMENT alias (#PCDATA)> +<!ELEMENT reporter_accessible (#PCDATA)> +<!ELEMENT cclist_accessible (#PCDATA)> <!ELEMENT exporter (#PCDATA)> <!ELEMENT urlbase (#PCDATA)> <!ELEMENT bug_status (#PCDATA)> @@ -35,6 +37,10 @@ <!ELEMENT dependson (#PCDATA)> <!ELEMENT blocked (#PCDATA)> <!ELEMENT cc (#PCDATA)> +<!ELEMENT group (#PCDATA)> +<!ELEMENT estimated_time (#PCDATA)> +<!ELEMENT remaining_time (#PCDATA)> +<!ELEMENT actual_time (#PCDATA)> <!ELEMENT long_desc (who, bug_when, thetext)> <!ELEMENT who (#PCDATA)> <!ELEMENT bug_when (#PCDATA)> diff --git a/checksetup.pl b/checksetup.pl index 3543b45ee..bc9aeab96 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -238,7 +238,7 @@ my $modules = [ }, { name => 'Template', - version => '2.07' + version => '2.08' }, { name => 'Text::Wrap', @@ -957,6 +957,7 @@ END js => sub { return $_; }, html_linebreak => sub { return $_; }, url_quote => sub { return $_; }, + xml => sub { return $_; }, quoteUrls => sub { return $_; }, bug_link => [ sub { return sub { return $_; } }, 1], csv => sub { return $_; }, diff --git a/globals.pl b/globals.pl index 51d6642fa..d4e4e452c 100644 --- a/globals.pl +++ b/globals.pl @@ -1794,6 +1794,8 @@ $::template ||= Template->new( # characters that need encoding. url_quote => \&Bugzilla::Util::url_quote , + xml => \&Bugzilla::Util::xml_quote , + quoteUrls => \"eUrls , bug_link => [ sub { @@ -27,7 +27,7 @@ use lib qw(.); require "CGI.pl"; -use vars qw($userid %COOKIE); +use vars qw($template $userid %COOKIE); use Bug; @@ -96,13 +96,12 @@ unless ($exporter =~ /($movers)/) { exit; } -my $xml = ""; -$xml .= Bug::XML_Header( Param("urlbase"), $Bugzilla::Config::VERSION, - Param("maintainer"), $exporter ); +my @bugs; + print "<P>\n"; foreach my $id (split(/:/, $::FORM{'buglist'})) { my $bug = new Bug($id, $::userid); - $xml .= $bug->emitXML; + push @bugs, $bug; if (!$bug->error) { my $exporterid = DBNameToIdAndCheck($exporter); @@ -137,7 +136,6 @@ foreach my $id (split(/:/, $::FORM{'buglist'})) { } } print "<P>\n"; -$xml .= Bug::XML_Footer; my $buglist = $::FORM{'buglist'}; $buglist =~ s/:/,/g; @@ -150,7 +148,11 @@ my $from = Param("moved-from-address"); $from =~ s/@/\@/; $msg .= "From: Bugzilla <" . $from . ">\n"; $msg .= "Subject: Moving bug(s) $buglist\n\n"; -$msg .= $xml . "\n"; + +$template->process("bug/show.xml.tmpl", { bugs => \@bugs }, \$msg) + || ThrowTemplateError($template->error()); + +$msg .= "\n"; open(SENDMAIL, "|/usr/lib/sendmail -ODeliveryMode=background -t -i") || diff --git a/show_bug.cgi b/show_bug.cgi index 377c7905d..52c7f83f9 100755 --- a/show_bug.cgi +++ b/show_bug.cgi @@ -28,7 +28,7 @@ require "CGI.pl"; ConnectToDatabase(); -use vars qw($template $vars $userid); +use vars qw($cgi $template $vars $userid); use Bug; @@ -38,36 +38,38 @@ if ($::FORM{'GoAheadAndLogIn'}) { quietly_check_login(); } -###################################################################### -# Begin Data/Security Validation -###################################################################### +# Editable, 'single' HTML bugs are treated slightly specially in a few places +my $single = !$cgi->param('format') + && (!$cgi->param('ctype') || $cgi->param('ctype') eq 'html'); -unless (defined ($::FORM{'id'})) { - my $format = GetFormat("bug/choose", $::FORM{'format'}, $::FORM{'ctype'}); - - print "Content-type: $format->{'contenttype'}\n\n"; - $template->process("$format->{'template'}", $vars) || +# If we don't have an ID, _AND_ we're only doing a single bug, then prompt +if (!defined $cgi->param('id') && $single) { + print "Content-type: text/html\n\n"; + $template->process("bug/choose.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; } my $format = GetFormat("bug/show", $::FORM{'format'}, $::FORM{'ctype'}); -# Make sure the bug ID is a positive integer representing an existing -# bug that the user is authorized to access. -ValidateBugID($::FORM{'id'}); - -###################################################################### -# End Data/Security Validation -###################################################################### - GetVersionTable(); -my $bug = new Bug($::FORM{'id'}, $userid); +my @bugs = (); -$vars->{'bug'} = $bug; +if ($single) { + my $id = $cgi->param('id'); + # Its a bit silly to do the validation twice - that functionality should + # probably move into Bug.pm at some point + ValidateBugID($id); + push @bugs, new Bug($id, $userid); +} else { + foreach my $id ($cgi->param('id')) { + my $bug = new Bug($id, $userid); + push @bugs, $bug; + } +} -ThrowCodeError("bug_error") if $bug->error; +$vars->{'bugs'} = \@bugs; # Next bug in list (if there is one) my @bug_list; diff --git a/t/004template.t b/t/004template.t index b3fdcc8b7..be0dd04ec 100644 --- a/t/004template.t +++ b/t/004template.t @@ -81,6 +81,7 @@ my $provider = Template::Provider->new( js => sub { return $_ } , strike => sub { return $_ } , url_quote => sub { return $_ } , + xml => sub { return $_ } , quoteUrls => sub { return $_ } , bug_link => [ sub { return sub { return $_; } }, 1] , csv => sub { return $_ } , diff --git a/template/en/default/bug/choose-xml.html.tmpl b/template/en/default/bug/choose-xml.html.tmpl deleted file mode 100644 index 045ad7c58..000000000 --- a/template/en/default/bug/choose-xml.html.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -<!-- 1.0@bugzilla.org --> -[%# 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 <gerv@gerv.net> - #%] - -[%# INTERFACE: - # This template has no interface. - #%] - -[% PROCESS global/header.html.tmpl - title = "Display bugs as XML" - %] - -<form method="get" action="xml.cgi"> - <table> - <tr> - <td> - Display bugs as XML by entering a list of bug numbers here: - </td> - <td> - <input name="id" size="30"> - <input type="submit" value="Display as XML"> - </td> - </tr> - - <tr> - <td> </td> - <td> - (e.g. 1000, 2467, 852) - </td> - </tr> - </table> -</form> - -[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/bug/choose.html.tmpl b/template/en/default/bug/choose.html.tmpl index a9a62567c..f965ccc4d 100644 --- a/template/en/default/bug/choose.html.tmpl +++ b/template/en/default/bug/choose.html.tmpl @@ -19,11 +19,9 @@ # Contributor(s): Gervase Markham <gerv@gerv.net> #%] -[% UNLESS header_done %] - [% PROCESS global/header.html.tmpl - title = "Search by bug number" - %] -[% END %] +[% PROCESS global/header.html.tmpl + title = "Search by bug number" + %] <form method="get" action="show_bug.cgi"> <p> diff --git a/template/en/default/bug/show.html.tmpl b/template/en/default/bug/show.html.tmpl index 46f8c4674..637583502 100644 --- a/template/en/default/bug/show.html.tmpl +++ b/template/en/default/bug/show.html.tmpl @@ -21,6 +21,9 @@ # Bradley Baetz <bbaetz@student.usyd.edu.au> #%] +[%# This script/template only handles one bug #%] +[% bug = bugs.0 %] + [% filtered_desc = bug.short_desc FILTER html %] [% filtered_timestamp = bug.delta_ts FILTER time %] [% PROCESS global/header.html.tmpl diff --git a/template/en/default/bug/show.xml.tmpl b/template/en/default/bug/show.xml.tmpl new file mode 100644 index 000000000..501ec2c17 --- /dev/null +++ b/template/en/default/bug/show.xml.tmpl @@ -0,0 +1,84 @@ +[%# 1.0@bugzilla.org #%] +[%# 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): Bradley Baetz <bbaetz@student.usyd.edu.au> + # + #%] +<?xml version="1.0" standalone="yes"?> +<!DOCTYPE bugzilla SYSTEM "[% Param('urlbase') %]bugzilla.dtd"> + +<bugzilla version="[% VERSION %]" + urlbase="[% Param('urlbase') %]" + maintainer="[% Param('maintainer') FILTER xml %]" +[% IF user.login %] + exporter="[% user.login FILTER xml %]" +[% END %] +> + +[% FOREACH bug = bugs %] + [% IF bug.error %] + <bug error="[% bug.error FILTER xml %]"> + <bug_id>[% bug.bug_id FILTER xml %]</bug_id> + </bug> + [% ELSE %] + <bug> + [% FOREACH field = bug.fields %] + [%+ PROCESS bug_field %] + [% END %] + + [%# Now handle 'special' fields #%] + [% FOREACH g = bug.groups %] + [% NEXT UNLESS g.ison %] + <group>[% g.name FILTER xml %]</group> + [% END %] + + [% FOREACH c = bug.longdescs %] + <long_desc> + <who>[% c.email FILTER xml %]</who> + <bug_when>[% c.time FILTER time FILTER xml %]</bug_when> + <thetext>[% c.body FILTER xml %]</thetext> + </long_desc> + [% END %] + + [% FOREACH a = bug.attachments %] + <attachment> + <attachid>[% a.attachid %]</attachid> + <date>[% a.date FILTER time FILTER xml %]</date> + <desc>[% a.description FILTER xml %]</desc> + </attachment> + [% END %] + </bug> + [% END %] +[% END %] + +</bugzilla> + +[% BLOCK bug_field %] + [% FOREACH val = bug.$field %] + [%# We need to handle some fields differently. This should become + # nicer once we have custfields, and a type attribute for the fields + #%] + [% IF field == 'reporter' OR field == 'assigned_to' OR + field == 'qa_contact' %] + [% val = val.email %] + [% ELSIF field == 'creation_ts' OR field == 'delta_ts' %] + [% val = val FILTER time %] + [% END %] + <[% field %]>[% val FILTER xml %]</[% field %]> + [% END %] +[% END %] @@ -28,30 +28,15 @@ use lib qw(.); require "CGI.pl"; -use Bug; +our $cgi; -use vars qw($template $vars $userid %COOKIE); +# Convert comma/space separated elements into separate params +my @ids = (); -ConnectToDatabase(); -quietly_check_login(); - -if (!defined $::FORM{'id'} || !$::FORM{'id'}) { - print "Content-Type: text/html\n\n"; - $template->process("bug/choose-xml.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - exit; +if (defined $cgi->param('id')) { + @ids = split (/[, ]+/, $cgi->param('id')); } -my $exporter = $::COOKIE{"Bugzilla_login"} || undef; - -my @ids = split (/[, ]+/, $::FORM{'id'}); - -print "Content-type: text/xml\n\n"; -print Bug::XML_Header(Param("urlbase"), $Bugzilla::Config::VERSION, - Param("maintainer"), $exporter); -foreach my $id (@ids) { - my $bug = new Bug(trim($id), $::userid); - print $bug->emitXML; -} +my $ids = join('', map { $_ = "&id=" . $_ } @ids); -print Bug::XML_Footer; +print $cgi->redirect("show_bug.cgi?ctype=xml$ids"); |