summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbbaetz%student.usyd.edu.au <>2002-12-15 18:23:55 +0100
committerbbaetz%student.usyd.edu.au <>2002-12-15 18:23:55 +0100
commit1cee4770ca5e09e3b56c0de0e8c77c2684542d18 (patch)
treea31b3c625607961094750db3f7619619a9d7767f
parentee84183ca9efa0839c49ad02f293d60db0a4d76f (diff)
downloadbugzilla-1cee4770ca5e09e3b56c0de0e8c77c2684542d18.tar.gz
bugzilla-1cee4770ca5e09e3b56c0de0e8c77c2684542d18.tar.xz
Bug 158499 - Templatise XML bug output
r=gerv, justdave a=justdave
-rwxr-xr-xBug.pm158
-rwxr-xr-xBugzilla/Bug.pm158
-rw-r--r--Bugzilla/Util.pm27
-rw-r--r--bugzilla.dtd8
-rwxr-xr-xchecksetup.pl3
-rw-r--r--globals.pl2
-rwxr-xr-xmove.pl16
-rwxr-xr-xshow_bug.cgi42
-rw-r--r--t/004template.t1
-rw-r--r--template/en/default/bug/choose-xml.html.tmpl51
-rw-r--r--template/en/default/bug/choose.html.tmpl8
-rw-r--r--template/en/default/bug/show.html.tmpl3
-rw-r--r--template/en/default/bug/show.xml.tmpl84
-rwxr-xr-xxml.cgi29
14 files changed, 230 insertions, 360 deletions
diff --git a/Bug.pm b/Bug.pm
index 7d7a1debc..251ad16e2 100755
--- a/Bug.pm
+++ b/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/&/&amp;/g;
- $_[0] =~ s/</&lt;/g;
- $_[0] =~ s/>/&gt;/g;
- $_[0] =~ s/\'/&apos;/g;
- $_[0] =~ s/\"/&quot;/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/&/&amp;/g;
- $_[0] =~ s/</&lt;/g;
- $_[0] =~ s/>/&gt;/g;
- $_[0] =~ s/\'/&apos;/g;
- $_[0] =~ s/\"/&quot;/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/\&/\&amp;/g;
+ $var =~ s/</\&lt;/g;
+ $var =~ s/>/\&gt;/g;
+ $var =~ s/\"/\&quot;/g;
+ $var =~ s/\'/\&apos;/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 &#013;, suitable for use in html attributes.
+=item C<xml_quote($val)>
+
+This is similar to C<html_quote>, except that ' is escaped to &apos;. This
+is kept separate from html_quote partly for compatibility with previous code
+(for &apos;) 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 => \&quoteUrls ,
bug_link => [ sub {
diff --git a/move.pl b/move.pl
index 1fcf35707..4807bf6d9 100755
--- a/move.pl
+++ b/move.pl
@@ -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>&nbsp;</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 %]
diff --git a/xml.cgi b/xml.cgi
index 91f8e8c03..f93c0e5c0 100755
--- a/xml.cgi
+++ b/xml.cgi
@@ -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");