Bug 158499 - Templatise XML bug output

r=gerv, justdave a=justdave
parent ee84183c
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
......@@ -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)>
......
......@@ -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 $_; },
......
......@@ -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 {
......
......@@ -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") ||
......
......@@ -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;
......
......@@ -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 $_ } ,
......
<!-- 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 %]
......@@ -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>
......
......@@ -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
......
[%# 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");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment