phpro / soap-client

A general purpose SOAP client for PHP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

client->login() returns the value of incorrect type

dmitriifrlv opened this issue · comments

Q A
Version 2.4.0

Support Question

Description

After updating "phpro/soap-client": "^1.7" to ver. 2.4.0 I've started to get an error when the client->login() function is executed:

Return value must be of type App\Type\LoginResponse, Phpro\SoapClient\Type\MixedResult returned in ../AppNameClient.php:30

I updated the app by following the guide - https://github.com/phpro/soap-client/blob/v2.0.0/UPGRADING.md and completing all the steps from a wizard - ./vendor/bin/soap-client wizard.

To reproduce

Composer.json :

{
  "require": {
    "sendgrid/sendgrid": "~7.8",
    "kreait/firebase-php": "~5.17",
    "phpro/soap-client": "^2.4.0",
    "ext-soap": "*",
    "http-interop/http-factory-guzzle": "^1.2"
  },
  "require-dev": {
    "phpunit/phpunit": "^8",
    "guzzlehttp/guzzle": "^7.5.0",
    "laminas/laminas-code": "^4.8.0"
  },
  "config": {
    "allow-plugins": {
      "php-http/discovery": true
    }
  }
}

Client factory:


use App\AppNameClient;
use App\AppNameClassmap;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Phpro\SoapClient\Soap\DefaultEngineFactory;
use Soap\ExtSoapEngine\ExtSoapOptions;
use Phpro\SoapClient\Caller\EventDispatchingCaller;
use Phpro\SoapClient\Caller\EngineCaller;

class AppNameClientFactory
{
    public static function factory(string $wsdl) : \App\AppNameClient
    {
        $engine = DefaultEngineFactory::create(
            ExtSoapOptions::defaults($wsdl, [
                'soap_version' => SOAP_1_2,
                'exceptions' => false,
                'stream_context' => stream_context_create([
                    'ssl' => [
                        'verify_peer' => false,
                        'verify_peer_name' => false,
                        'verify_host' => false,
                        'allow_self_signed' => true,
                    ]
                ])
            ])
                ->withClassMap(AppNameClassmap::getCollection())
        );

        $eventDispatcher = new EventDispatcher();
        $caller = new EventDispatchingCaller(new EngineCaller($engine), $eventDispatcher);

        return new AppNameClient($caller);
    }
}

App:

$this->client = App\AppNameClientFactory::factory($wsdl);
$response = $this->client->login(new App\Type\Login($this->username, $this->password));
                                               ^^at this step I get the error Return value must be of type App\Type\LoginResponse, Phpro\SoapClient\Type\MixedResult returned

I made sure that the login and password were correct by successfully logging in to the web client of a device. Also, I checked that $wsdl contains the correct XML with valid markup in .wsdl format.

What can be the reason for this error?

Hello,

In V2, we use psr http clients by default.
This means that the stream_context option is not being used. Instead you must configure these settings on the http client.

Another option is to manually configure the ext-soap client transport we used by default in v1

@veewee Thank you for responding so quickly! I'll try both options to tackle the issue. I'd greatly appreciate it if it's possible to leave this issue open until then.

@veewee I decided to configure the settings on the HTTP client which is guzzlehttp/guzzle in my case:

        $client = new \GuzzleHttp\Client([
            'defaults' => [
                'verify'  => false
            ]
        ]);

The code for generating engine looks like that now :

   $engine = DefaultEngineFactory::create(
            ExtSoapOptions::defaults($wsdl, [
                'soap_version' => SOAP_1_2,
                'exceptions' => false
            ])
                ->withClassMap(ParkChampClassmap::getCollection()),
                $transport = Psr18Transport::createForClient(
                    new PluginClient(
                        $client,
                    )
                )
        );

However, I still get the error:

 Return value must be of type App\Type\LoginResponse, Phpro\SoapClient\Type\MixedResult returned in .../AppNameClient.php:30

AppNameClient.php:30 is :

   28: public function login(\App\Type\Login $parameters) : \App\Type\LoginResponse
   29: {
   30:    return ($this->caller)('login', $parameters);
   31:  }

I'm sure the login parameters are correct. Could you tell me please what else may be wrong?

What value is inside the mixed result?
Does the login response class extend ResultInterface?

@veewee Thank you for your attention!

What value is inside the mixed result?

Inside the mixed result is an object of type Phpro\SoapClient\Type\MixedResult :

Phpro\SoapClient\Type\MixedResult Object
(
    [result:Phpro\SoapClient\Type\MixedResult:private] => SoapFault Object
        (
            [message:protected] => looks like we got no XML document
            [string:Exception:private] => 
            [code:protected] => 0
            [file:protected] => readers/vendor/php-soap/ext-soap-engine/src/ExtSoapDecoder.php
            [line:protected] => 26
            [trace:Exception:private] => Array
                (
                    [0] => Array
                        (
                            [file] => readers/vendor/php-soap/ext-soap-engine/src/ExtSoapDecoder.php
                            [line] => 26
                            [function] => __soapCall
                            [class] => SoapClient
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => Array
                                        (
                                            [0] => 
                                        )

                                )

                        )

                    [1] => Array
                        (
                            [file] => readers/vendor/php-soap/ext-soap-engine/src/ExtSoapDriver.php
                            [line] => 59
                            [function] => decode
                            [class] => Soap\ExtSoapEngine\ExtSoapDecoder
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => Soap\Engine\HttpBinding\SoapResponse Object
                                        (
                                            [payload:Soap\Engine\HttpBinding\SoapResponse:private] => 404 - Not found | We searched the space, but we could not find the page you are looking for.

                                        )

                                )

                        )

                    [2] => Array
                        (
                            [file] => readers/vendor/php-soap/engine/src/SimpleEngine.php
                            [line] => 27
                            [function] => decode
                            [class] => Soap\ExtSoapEngine\ExtSoapDriver
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => Soap\Engine\HttpBinding\SoapResponse Object
                                        (
                                            [payload:Soap\Engine\HttpBinding\SoapResponse:private] => 404 - Not found | We searched the space, but we could not find the page you are looking for.

                                        )

                                )

                        )

                    [3] => Array
                        (
                            [file] => readers/vendor/php-soap/engine/src/LazyEngine.php
                            [line] => 28
                            [function] => request
                            [class] => Soap\Engine\SimpleEngine
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => Array
                                        (
                                            [0] => App\Type\Login Object
                                                (
                                                    [username:App\Type\Login:private] => correctUsername
                                                    [password:App\Type\Login:private] => correctPassword
                                                )

                                        )

                                )

                        )

                    [4] => Array
                        (
                            [file] => readers/vendor/phpro/soap-client/src/Phpro/SoapClient/Caller/EngineCaller.php
                            [line] => 27
                            [function] => request
                            [class] => Soap\Engine\LazyEngine
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => Array
                                        (
                                            [0] => App\Type\Login Object
                                                (
                                                    [username:App\Type\Login:private] => correctUsername
                                                    [password:App\Type\Login:private] => correctPassword
                                                )

                                        )

                                )

                        )

                    [5] => Array
                        (
                            [file] => readers/vendor/phpro/soap-client/src/Phpro/SoapClient/Caller/EventDispatchingCaller.php
                            [line] => 30
                            [function] => __invoke
                            [class] => Phpro\SoapClient\Caller\EngineCaller
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => App\Type\Login Object
                                        (
                                            [username:App\Type\Login:private] => correctUsername
                                            [password:App\Type\Login:private] => correctPassword
                                        )

                                )

                        )

                    [6] => Array
                        (
                            [file] => readers/www/v4/src/AppNameClient.php
                            [line] => 34
                            [function] => __invoke
                            [class] => Phpro\SoapClient\Caller\EventDispatchingCaller
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => login
                                    [1] => App\Type\Login Object
                                        (
                                            [username:App\Type\Login:private] => correctUsername
                                            [password:App\Type\Login:private] => correctPassword
                                        )

                                )

                        )

                    [7] => Array
                        (
                            [file] => readers/www/v4/libs/devices/JakinACTA4Controller.php
                            [line] => 82
                            [function] => login
                            [class] => App\AppNameClient
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => App\Type\Login Object
                                        (
                                            [username:App\Type\Login:private] => correctUsername
                                            [password:App\Type\Login:private] => correctPassword
                                        )

                                )

                        )

                    [8] => Array
                        (
                            [file] => readers/www/v4/libs/controllers/BuildingController.php
                            [line] => 213
                            [function] => login
                            [class] => JakinACTA4Controller
                            [type] => ->
                            [args] => Array
                                (
                                )

                        )

                    [9] => Array
                        (
                            [file] => readers/www/v4/libs/controllers/BuildingController.php
                            [line] => 20
                            [function] => login
                            [class] => BuildingController
                            [type] => ->
                            [args] => Array
                                (
                                )

                        )

                    [10] => Array
                        (
                            [file] => readers/www/v4/libs/controllers/BuildingController.php
                            [line] => 243
                            [function] => getLogs
                            [class] => BuildingController
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => Array
                                        (
                                            [action] => getLogs
                                        )

                                )

                        )

                    [11] => Array
                        (
                            [file] => readers/www/v4/controllers/mock/building.php
                            [line] => 48
                            [function] => processRequest
                            [class] => BuildingController
                            [type] => ->
                            [args] => Array
                                (
                                    [0] => Array
                                        (
                                            [action] => getLogs
                                        )

                                )

                        )

                )

            [previous:Exception:private] => 
            [faultstring] => looks like we got no XML document
            [faultcode] => Sender
            [faultcodens] => http://www.w3.org/2003/05/soap-envelope
            [faultactor] => 
            [detail] => 
            [_name] => 
            [headerfault] => 
        )

)
<br />
<b>Fatal error</b>:  Uncaught TypeError: App\AppNameClient::login(): Return value must be of type App\Type\LoginResponse, Phpro\SoapClient\Type\MixedResult returned in readers/www/v4/src/AppNameClient.php:36
Stack trace:
#0 readers/www/v4/libs/devices/JakinACTA4Controller.php(82): App\AppNameClient-&gt;login(Object(App\Type\Login))
#1 readers/www/v4/libs/controllers/BuildingController.php(213): JakinACTA4Controller-&gt;login()
#2 readers/www/v4/libs/controllers/BuildingController.php(20): BuildingController-&gt;login()
#3 readers/www/v4/libs/controllers/BuildingController.php(243): BuildingController-&gt;getLogs(Array)
#4 readers/www/v4/controllers/mock/building.php(48): BuildingController-&gt;processRequest(Array)
#5 {main}
  thrown in <b>readers/www/v4/src/AppNameClient.php</b> on line <b>36</b><br />


Does the login response class extend ResultInterface?

Yes, this function is inside AppNameClient which was generated by the wizard:

class LoginResponse implements ResultInterface

Strange... A soap fault should be an instance of exception and be thrown as exception.

} catch (\Exception $exception) {

In this case you get a 404. Can you verify the endpoints are correct?
We're you previously also manually selecting soap 1.2?

Can you verify the endpoints are correct?

I can confirm that the endpoints are correct. Also, when I use the branch with the previous soap version installed everything works.

We're you previously also manually selecting soap 1.2?

Yes, I used all the same settings. Here is the code for the factory which was used with "phpro/soap-client": "^1.7"

    public static function factory(string $wsdl, string $location) : \App\AppNameClient
    {
        $engine = ExtSoapEngineFactory::fromOptions(
            ExtSoapOptions::defaults($wsdl, [
                'soap_version' => SOAP_1_2,
                'exceptions' => false,
                'location' => $location,
                'stream_context' => stream_context_create([
                    'ssl' => [
                        'verify_peer' => false,
                        'verify_peer_name' => false,
                        'verify_host' => false,
                        'allow_self_signed' => true,
                    ]
                ])
            ])->withClassMap(AppNameClassmap::getCollection())
        );
        $eventDispatcher = new EventDispatcher();

        return new AppNameClient($engine, $eventDispatcher);
    }

Here is the composer file for the previous version:

{
  "require": {
    "sendgrid/sendgrid": "~7.8",
    "kreait/firebase-php": "~5.17",
    "phpro/soap-client": "^1.7",
    "ext-soap": "*"
  },
  "require-dev": {
    "phpunit/phpunit": "^8",
    "guzzlehttp/guzzle": "^6.3",
    "laminas/laminas-code": "^3.4.1"
  }
}

There are 2 things in there:

Exceptions are disabled, which might explain the error not being thrown and instead being returned.

You pass the location to the old implementation. This one will be ignored since you use the psr http client transport. Instead, you need to register it on your guzzle cliënt.

Hope this fixed the issue for you .
If not, you might want to use a logger plugin on the http client that will tell you more about the http messages being sent and received.

@veewee Thank you for your help!

When I removed disabling exceptions and added location as 'base_uri'to guzzle client I indeed received a different error:

Uncaught SoapFault: looks like we got no XML document in /vendor/php-soap/ext-soap-engine/src/ExtSoapDecoder.php:26

I'll try to debug it further.

Another option is to manually configure the ext-soap client transport we used by default in v1

If I decide to go this way, is the process of configuring ext-soap client transport the same as what I did for the guzzle client, where the 1st step is to create the client instance with an array of options and then pass this client instance to the engine as a second argument?

Setting the base_uri won't be sufficient since an absolute url is passed. You need to change the base location.
You can do this by using httplugs Plugin client around guzzle with this plugin
https://docs.php-http.org/en/latest/plugins/request-uri-manipulations.html

The exception will be the same as what you pasted previously.

@dmitriifrlv I suppose this issue can be marked as fixed? Feel free to reopen if you have any additional questions.