ZF-6347: DefaultComplexType strategy doesn't support nillable class properties
Description
The {{DefaultComplexType}} WSDL strategy only uses the first type declared in the {{@var}} docblock of a class property. Suppose the following docblock:
/** @var int|null My nillable integer variable */
public $myvariable;
In this case the variable is not considered nillable and a C# client (for example) will use the "int" type (which cannot be null) instead of "int?" (which can be null). There is sometimes a big difference between "0" and "null" for certain fields, especially booleans where null could mean "undefined".
Of course the following case also causes problems with the current code:
/** @var null|int My nillable integer variable */
public $myvariable;
Only the "null" type would be taken into account, and, well, this is not a type.
Comments
Posted by Fabien Crespel (fcrespel) on 2009-04-19T14:28:54.000+0000
This patch fixes the issue by adding the {{nillable}} attribute to the {{element}} node when "null" is present among the {{@var}} types. The first non-null type is used for the {{type}} attribute.
Posted by Robert F. Ludwick (rfludwick) on 2009-05-04T14:51:51.000+0000
Wouldn't this only fix nillable complex types? What if you wanted to make a string member var null, like so:
The {{DefaultComplexType}} strategy, at least in my usage experience, doesn't handle those, as {{Zend_Soap_Wsdl}} does instead.
Posted by Fabien Crespel (fcrespel) on 2009-05-07T05:39:50.000+0000
String member variables can also be null. Actually, it works with any type, and for example I use {{string}}, {{int}} and {{bool}} nillable class properties in a personal project.
{{DefaultComplexType}} iterates over the class properties, detects the "null" (with my patch), and then calls {{$this->getContext()->getType()}}. So getting the type goes back to Zend_Soap_Wsdl, yes, but only after detecting "null". Whether the actual type is a native type handled by Zend_Soap_Wsdl directly, or a complexType handled by a strategy, doesn't matter :)
Posted by Amr Mostafa (alienbrain) on 2009-07-29T09:30:55.000+0000
Does this apply to class methods and functions as well, or would this be an issue of AutoDiscover?
Posted by Fabien Crespel (fcrespel) on 2009-07-30T04:44:11.000+0000
This only applies to class properties (variables).
For class methods, you can make parameters optional (nillable) by giving them a null default value. This would only work with ZF 1.9 and the document/literal style though, as the rpc style doesn't let you use nillable parts. See ZF-6349 and ZF-6351.
Posted by Amr Mostafa (alienbrain) on 2009-07-30T07:23:47.000+0000
Very helpful, thank you.
Posted by Alex (aalbino) on 2009-11-02T13:09:25.000+0000
The .diff file, when applied to Zend_Soap_Wsdl_Strategy_DefaultComplexType, worked for me. Because Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex extends the "DefaultComplexType" strategy, it too correctly picked up on the following php docblock:
@var string|null
...And made the variable "nillable"
Thanks!
PS - Any chance this fix can be applied to the trunk?
Posted by Ramon Henrique Ornelas (ramon) on 2010-08-25T21:27:36.000+0000
I think that this issue was fixed in trunk by [~rquadling] see ZF-10153.
Posted by Richard Quadling (rquadling) on 2010-09-13T09:18:54.000+0000
My patch works by relying on a default value not being set for the property, rather than examining the different @var values.
e.g.
/** * Date Added * * @var xsd:datetime */ public $DateAdded;
becomes ...
in the wsdl file.
This is working for me (PHP) and my client's client (.NET based - I've no idea about their code).
Everyone happy.
And if you are wondering how xsd:datetime is working, I've made another patch to the AutoDiscovery code to allow for standard XSD types to be declared. Not 100% of them, but those I use.
I don't enough about getting my patches released, so hopefully someone can review them and make suggestions.
Posted by oscar (oscaroxy) on 2013-01-22T21:12:50.000+0000
If I wrote:
class MyClass{ /* * @var xsd:dateTime */ public $myProp;
}
I obtain an error, while if I write:
class MyClass{ /* * @var dateTime */ public $myProp;
}
in wsdl I read "complex object" with namespase tns and not xsd. Why? How do I do for resolve this problem? thanks
Posted by oscar (oscaroxy) on 2013-01-22T21:12:50.000+0000
If I wrote:
class MyClass{ /* * @var xsd:dateTime */ public $myProp;
}
I obtain an error, while if I write:
class MyClass{ /* * @var dateTime */ public $myProp;
}
in wsdl I read "complex object" with namespase tns and not xsd. Why? How do I do for resolve this problem? thanks