]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 494427: Instead of sending <nil> for undef elements in the WebService, just strip...
authormkanat%bugzilla.org <>
Sat, 4 Jul 2009 12:06:57 +0000 (12:06 +0000)
committermkanat%bugzilla.org <>
Sat, 4 Jul 2009 12:06:57 +0000 (12:06 +0000)
Patch by Rosie Clarkson <rosie.clarkson@planningportal.gov.uk> r=mkanat, a=mkanat

Bugzilla/WebService.pm
Bugzilla/WebService/Server/XMLRPC.pm

index eddc6c24c0945158b00cf1ab5c3f4d6590e263cb..dce62b92155c379a387c78fac206c90e2a8a6586 100755 (executable)
@@ -14,6 +14,9 @@
 #
 # Contributor(s): Marc Schumann <wurblzap@gmail.com>
 #                 Max Kanat-Alexander <mkanat@bugzilla.org>
+#                 Rosie Clarkson <rosie.clarkson@planningportal.gov.uk>
+#                 
+# Portions © Crown copyright 2009 - Rosie Clarkson (development@planningportal.gov.uk) for the Planning Portal
 
 # This is the base class for $self in WebService method calls. For the 
 # actual RPC server, see Bugzilla::WebService::Server and its subclasses.
@@ -273,8 +276,11 @@ Bugzilla also accepts an element called C<< <nil> >>, as specified by
 the XML-RPC extension here: L<http://ontosys.com/xml-rpc/extensions.php>, 
 which is always considered to be C<undef>, no matter what it contains.
 
-Bugzilla uses C<< <nil/> >> values to return C<int>, C<double>, or 
-C<dateTime.iso8601> values which are undefined.
+Bugzilla does not use C<< <nil> >> values in returned data, because currently
+most clients do not support C<< <nil> >>. Instead, any fields with C<undef>
+values will be stripped from the response completely. Therefore
+B<the client must handle the fact that some expected fields may not be 
+returned>.
 
 =begin private
 
index 2b30bea8174d9312ffc1b6ee62e1ebb993cedbf2..8954969c71dd09c5fde36c19e1b0f75874afbbd9 100644 (file)
@@ -141,6 +141,7 @@ sub _validation_subs {
 # This package exists to fix a UTF-8 bug in SOAP::Lite.
 # See http://rt.cpan.org/Public/Bug/Display.html?id=32952.
 package Bugzilla::XMLRPC::Serializer;
+use Scalar::Util qw(blessed);
 use strict;
 # We can't use "use base" because XMLRPC::Serializer doesn't return
 # a true value.
@@ -180,6 +181,55 @@ sub encode_object {
         : @encoded;
 }
 
+# Removes undefined values so they do not produce invalid XMLRPC.
+sub envelope {
+    my $self = shift;
+    my ($type, $method, $data) = @_;
+    # If the type isn't a successful response we don't want to change the values.
+    if ($type eq 'response'){
+        $data = _strip_undefs($data);
+    }
+    return $self->SUPER::envelope($type, $method, $data);
+}
+
+# In an XMLRPC response we have to handle hashes of arrays, hashes, scalars,
+# Bugzilla objects (reftype = 'HASH') and XMLRPC::Data objects.
+# The whole XMLRPC::Data object must be removed if its value key is undefined
+# so it cannot be recursed like the other hash type objects.
+sub _strip_undefs {
+    my ($initial) = @_;
+    if (ref $initial eq "HASH" || (blessed $initial && $initial->isa("HASH"))) {
+        while (my ($key, $value) = each(%$initial)) {
+            if ( !defined $value
+                 || (blessed $value && $value->isa('XMLRPC::Data') && !defined $value->value) )
+            {
+                # If the value is undefined remove it from the hash.
+                delete $initial->{$key};
+            }
+            else {
+                $initial->{$key} = _strip_undefs($value);
+            }
+        }
+    }
+    if (ref $initial eq "ARRAY" || (blessed $initial && $initial->isa("ARRAY"))) {
+        for (my $count = 0; $count < scalar @{$initial}; $count++) {
+            my $value = $initial->[$count];
+            if ( !defined $value
+                 || (blessed $value && $value->isa('XMLRPC::Data') && !defined $value->value) )
+            {
+                # If the value is undefined remove it from the array.
+                splice(@$initial, $count, 1);
+                $count--;
+            }
+            else {
+                $initial->[$count] = _strip_undefs($value);
+            }
+        }
+    }
+    return $initial;
+}
+
+
 sub BEGIN {
     no strict 'refs';
     for my $type (qw(double i4 int dateTime)) {