]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 158499 - Templatise XML bug output
authorbbaetz%student.usyd.edu.au <>
Sun, 15 Dec 2002 17:23:55 +0000 (17:23 +0000)
committerbbaetz%student.usyd.edu.au <>
Sun, 15 Dec 2002 17:23:55 +0000 (17:23 +0000)
r=gerv, justdave
a=justdave

14 files changed:
Bug.pm
Bugzilla/Bug.pm
Bugzilla/Util.pm
bugzilla.dtd
checksetup.pl
globals.pl
move.pl
show_bug.cgi
t/004template.t
template/en/default/bug/choose-xml.html.tmpl [deleted file]
template/en/default/bug/choose.html.tmpl
template/en/default/bug/show.html.tmpl
template/en/default/bug/show.xml.tmpl [new file with mode: 0644]
xml.cgi

diff --git a/Bug.pm b/Bug.pm
index 7d7a1debc78c3958499e952368ed63bdf97b014a..251ad16e2d3cbb58bbee9c07d01c3569dd72b829 100755 (executable)
--- 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;
index 7d7a1debc78c3958499e952368ed63bdf97b014a..251ad16e2d3cbb58bbee9c07d01c3569dd72b829 100755 (executable)
@@ -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;
index efd107c0ad7533c10ba63730b70b2f99e68257c9..5aecb5ad97a571de12ae7973ba4bf55ceb66398f 100644 (file)
 
 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
index 0445d0a4e445c75f6421d3703ae1a6c017f4519f..aecf9920d209d3cc75420dfa060f5cc1c8360365 100644 (file)
@@ -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)>
 <!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)>
index 3543b45ee2feec24ca0c40b638c0a365171b6281..bc9aeab96fea3018c21bce9858da357c49bf4cd5 100755 (executable)
@@ -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 $_; },
index 51d6642fa9332ad0a491fc84b0e2899967aad634..d4e4e452c9932fd4d70d5bff78e234482538a839 100644 (file)
@@ -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 1fcf3570712963d6bb45fcccdfc43837059b2af8..4807bf6d97f1e5e1859b8083a0f9c4eafcc7eb34 100755 (executable)
--- 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") ||
index 377c7905d24f21b5309a20edf788ec94d6815dd9..52c7f83f940441578173e04613e9430c5c7dfa31 100755 (executable)
@@ -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;
index b3fdcc8b7921549c33675db121798aca7128df63..be0dd04ec65e8fa09542527ca1235891f25ff5e7 100644 (file)
@@ -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 (file)
index 045ad7c..0000000
+++ /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 %]
index a9a62567c16da96e7a107ea1c66247ce8e4db6c1..f965ccc4d6e9d171a88f812331ba3a31d15b310a 100644 (file)
   # 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>
index 46f8c4674ba5f8b3ea5a8e3855dcfb5725cf5d28..637583502b86b140423f338a56d3c0376f5a9196 100644 (file)
@@ -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 (file)
index 0000000..501ec2c
--- /dev/null
@@ -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 91f8e8c03152e072a45ca2e636c978cc27eea0e7..f93c0e5c0efb9865dd80287c18ac9f4d056140b9 100755 (executable)
--- 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");