phpro / soap-client

A general purpose SOAP client for PHP
MIT License
857 stars 175 forks source link

Wrong cardinality in created class #346

Closed fbecker-complex closed 3 years ago

fbecker-complex commented 3 years ago

Bug Report

Q A
Version 1.4.1

Current behavior

This wsdl-snippet: image

Creates this class: `class ArrayOfContact {

/**
 * @var \WebConnector\Contact\Type\Contact
 */
private $Contact;

/**
 * @return \WebConnector\Contact\Type\Contact
 */
public function getContact()
{
    return $this->Contact;
}

/**
 * @param \WebConnector\Contact\Type\Contact $Contact
 * @return ArrayOfContact
 */
public function withContact($Contact)
{
    $new = clone $this;
    $new->Contact = $Contact;

    return $new;
}

}`

Problem:

ArrayOfContact only holds 1 Contact. So my call to readMultiple(): ArrayOfContact really just returns Contact and isn't doing more than read.

Full wsdl to reproduce behaviour: http://webconnector.tso.de/api/wsdl/Contact.wsdl

Expected behavior

I would expect the class to hold an array of contacts, over which I can iterate.

veewee commented 3 years ago

You can use the iterator assembler for this specific issue. More info: https://github.com/phpro/soap-client/blob/master/docs/known-issues/ext-soap.md#occurs

The code will still typehint as- if it is one contact, bit it will contain an array of contacts.

staabm commented 3 years ago

(I am another developer within Felix' team)

thx for the fast reply on this issue. We got a few questions regarding the possible solutions to our problem

It is possible that the WSDL file contains minOccurs and maxOccurs on XSD elements. Ext-soap will not make this information available through the public API of the SOAP client. Therefore, we cannot predict during code generation if a type will definitely be an array or possibly be nullable.

Currently, this issue can be avoided by not generating too strict types in the soap-client and optionally by using the IteratorAssembler.

A better solution would be to parse the WSDL manually and add that information to the metadata. From that point on we can take this information into consideration during code generation.

what does 'add that information to the metadata' mean in that context?

we are not sure whether changing generated code is a good idea, since this means we loose the ability to re-generate it again later on when the wsdl changes, right?

veewee commented 3 years ago

Hello @staabm ,

You can control how to generate code with assemblers. You don't have to change any code manually, but instead configure how the code is generated.

More info: https://github.com/phpro/soap-client/blob/master/docs/code-generation/configuration.md#configuration

So basically you can add a rule that checks for a type match on ^ArrayOf(.*) and apply the IteratorAssembler on these types. Something like this:

    ->addRule(new Rules\TypenameMatchesRule(
        new Rules\AssembleRule(new Assembler\IteratorAssembler()),
        '/^ArrayOf(.*)$/'
    ))

This will then apply an iterator on all generated ArrayOf* classes. (Of course, you need to regenerate after changing the config)

About type strictness : since there are some issues with the min and max bounds - I personally don't use strict types with the soap client. Instead I enforce in my applications.

what does 'add that information to the metadata' mean in that context?

That is currently not implemented yet : it means that this package could manually parse a WSDL file instead of using the information available in ext-soap. Thay way we have access to all the data and could use that to improve code generation. Internally, the system uses an own metadata representation that needs to be enriched with the WSDL data.

veewee commented 1 year ago

Hello,

We noticed this issue got reported many times and want to tackle it at its core! Therefore, we've planned a project that will work on better types support. It’s going to be a huge project, so we are looking for ways to make development possible during our business hours instead of in our developers precious spare time.

In case you want this feature as badly as us: find out how you can support this project here 💚!

staabm commented 1 year ago

thx for the effort. I just added you to our github sponsors companies sponsoring list, so you can make better typing / static analysis support happen in soap-client

veewee commented 1 year ago

That is awesome ❤️ ! Thanks @staabm!