@enterable_products %milestoneurl %prodmaxvotes);
use CGI::Carp qw(fatalsToBrowser);
-my %ok_field;
use Attachment;
use Bugzilla::Config;
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}++;
}
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.
#
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;
my @depends = EmitDependList("blocked", "dependson", $bug_id);
if (@depends) {
$self->{'dependson'} = \@depends;
- }
+ }
my @blocked = EmitDependList("dependson", "blocked", $bug_id);
if (@blocked) {
$self->{'blocked'} = \@blocked;
&& ($membercontrol == CONTROLMAPMANDATORY);
push (@groups, { "bit" => $groupid,
+ "name" => $name,
"ison" => $ison,
"ingroup" => $ingroup,
"mandatory" => $ismandatory,
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;
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;
@enterable_products %milestoneurl %prodmaxvotes);
use CGI::Carp qw(fatalsToBrowser);
-my %ok_field;
use Attachment;
use Bugzilla::Config;
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}++;
}
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.
#
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;
my @depends = EmitDependList("blocked", "dependson", $bug_id);
if (@depends) {
$self->{'dependson'} = \@depends;
- }
+ }
my @blocked = EmitDependList("dependson", "blocked", $bug_id);
if (@blocked) {
$self->{'blocked'} = \@blocked;
&& ($membercontrol == CONTROLMAPMANDATORY);
push (@groups, { "bit" => $groupid,
+ "name" => $name,
"ison" => $ison,
"ingroup" => $ingroup,
"mandatory" => $ismandatory,
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;
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;
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:
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;
return $str;
}
-# Bug 67077
sub format_time {
my ($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;
}
html_quote($var);
url_quote($var);
value_quote($var);
+ xml_quote($var);
# Functions for searching
$loc = lsearch(\@arr, $val);
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
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)>
<!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)>
},
{
name => 'Template',
- version => '2.07'
+ version => '2.08'
},
{
name => 'Text::Wrap',
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 $_; },
# characters that need encoding.
url_quote => \&Bugzilla::Util::url_quote ,
+ xml => \&Bugzilla::Util::xml_quote ,
+
quoteUrls => \"eUrls ,
bug_link => [ sub {
require "CGI.pl";
-use vars qw($userid %COOKIE);
+use vars qw($template $userid %COOKIE);
use Bug;
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);
}
}
print "<P>\n";
-$xml .= Bug::XML_Footer;
my $buglist = $::FORM{'buglist'};
$buglist =~ s/:/,/g;
$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") ||
ConnectToDatabase();
-use vars qw($template $vars $userid);
+use vars qw($cgi $template $vars $userid);
use Bug;
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;
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 $_ } ,
+++ /dev/null
-<!-- 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 %]
# 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>
# 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
--- /dev/null
+[%# 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 %]
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");