Issues

ZF-6742: ArrayOfTypeSequence strategy doesn't support complex types

Description

The {{ArrayOfTypeSequence}} WSDL strategy can only add arrays of basic xsd types like int, string, etc. Currently it is not possible to use it with singular complex types or arrays of complex types.

I know there is also an {{ArrayOfTypeComplex}} strategy, but it uses {{soap-enc:Array}} arrays while {{ArrayOfTypeSequence}} uses a sequence containing an unbounded element. The latter is WS-I Basic Profile 1.1 compliant, the former isn't but still commonly used, so it makes sense to have both. Additionally, {{ArrayOfTypeSequence}} supports multi-dimensional arrays (like {{MyComplexType[][]}}) while {{ArrayOfTypeComplex}} doesn't.

The patch attached to this issue adds support for complex types in {{ArrayOfTypeSequence}} the same way {{ArrayOfTypeComplex}} does: by extending the {{DefaultComplexType}} strategy and calling {{parent::addComplexType($type)}} when appropriate.

Now, I'm not sure this patch is the best way to do things... Ideally I think there should be 2 kinds of strategies in {{Zend_Soap_Wsdl}}: one for singular complex types, and one for arrays. But as it is, this patch is the easiest solution and it imitates what already exists in {{ArrayOfTypeComplex}}. Comments are welcome :)

Comments

Assigned to me

I really appreciate that this patch was added. It has been working great for acheiving WS-I compliance. Things work great when defining arrays of simpleTypes and complexTypes, such as:

@param string[] @param Zend_SomeMadeUpClass[]

However, for double nested arrays to work, a patch must be made, such as:

@param string[][] @param Zend_SomeMadeUpClass[][]

The problem is that each array creates a complex type of 'ArrayofString' or 'ArrayofZend_SomeMadeUpClass' with the appropriate 'xsd:string' or 'tns:Zend_SomeMadeUpClass' type, but when complex types of those complex types are made, the setAttribute('type', $childTypeName); on line 136 does not prepend 'tns:' for 'ArrayofString' or 'ArrayofZend_SomeMadeUpClass'.

Basically, I made it so the function prepends 'tns:' when child exists in the context type list.

protected function _addElementFromWsdlAndChildTypes($arrayType, $childTypeName)
{
    if (!in_array($arrayType, $this->getContext()->getTypes())) {
        // IF STATEMENT ADDED FOR PATCH
        if (in_array($childTypeName, $this->getContext()->getTypes())) {
            $childTypeName = 'tns:' . $childTypeName;
        }

        $dom = $this->getContext()->toDomDocument();

I also want to add that this makes it possible to do as many array nestings as you like.

I ran tests through SoapUI with tenth level nested arrays of complextypes (because who doesn't want that).

Oh you're right, I hadn't taken that case into account - thanks for testing!

Here is an updated version of my patch with a different fix.

Given that {{_getTypeNameBasedOnNestingLevel()}} returns a prefixed type when it's singular, I thought it would be better to make its behavior consistent and return a prefixed {{ArrayOf}} type (with "tns:").

In consequence, I added a {{substr()}} to remove any prefix from {{$complexTypeName}} in {{addComplexType()}} (line 40). This way, {{_addElementFromWsdlAndChildTypes()}} is always given the correct parameters without having to check/modify them.

Great work Fabien. All testing on my end works like a charm with your patch.

I applied the patch to trunk, it should be included in version 1.9