Skip to content

Commit 550f841

Browse files
authored
fix(laravel-soap-126): Arguments wrong passed with call method (#129)
* fix(laravel-soap-126): Arguments wrong passed with call method If a soap call was made with `client->call('action', arrayParameters)` the parameters were not included because its need to be wrapped in an array again. Also the faker engine now has the right soap options in the request. * Apply fixes from StyleCI (#130) Co-authored-by: Gregor Becker <[email protected]> * refactor(laravel-soap-126): fix tests Co-authored-by: Gregor Becker <[email protected]>
1 parent ab8f44c commit 550f841

12 files changed

+514
-15
lines changed

src/Driver/ExtSoap/AbusedClient.php

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,49 @@
44

55
namespace CodeDredd\Soap\Driver\ExtSoap;
66

7-
use Phpro\SoapClient\Soap\Driver\ExtSoap\AbusedClient as PhproAbusedClient;
87
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;
8+
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptionsResolverFactory;
99
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;
10+
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;
1011
use Phpro\SoapClient\Xml\SoapXml;
1112

12-
class AbusedClient extends PhproAbusedClient
13+
class AbusedClient extends \SoapClient
1314
{
14-
public static function createFromOptions(ExtSoapOptions $options): PhproAbusedClient
15+
/**
16+
* @var SoapRequest|null
17+
*/
18+
protected $storedRequest;
19+
20+
/**
21+
* @var SoapResponse|null
22+
*/
23+
protected $storedResponse;
24+
25+
// @codingStandardsIgnoreStart
26+
/**
27+
* Internal SoapClient property for storing last request.
28+
*
29+
* @var string
30+
*/
31+
protected $__last_request = '';
32+
// @codingStandardsIgnoreEnd
33+
34+
// @codingStandardsIgnoreStart
35+
/**
36+
* Internal SoapClient property for storing last response.
37+
*
38+
* @var string
39+
*/
40+
protected $__last_response = '';
41+
// @codingStandardsIgnoreEnd
42+
43+
public function __construct($wsdl, array $options = [])
44+
{
45+
$options = ExtSoapOptionsResolverFactory::createForWsdl($wsdl)->resolve($options);
46+
parent::__construct($wsdl, $options);
47+
}
48+
49+
public static function createFromOptions(ExtSoapOptions $options): self
1550
{
1651
return new self($options->getWsdl(), $options->getOptions());
1752
}
@@ -24,4 +59,34 @@ public function __doRequest($request, $location, $action, $version, $oneWay = 0)
2459

2560
return $this->storedResponse ? $this->storedResponse->getResponse() : '';
2661
}
62+
63+
public function collectRequest(): SoapRequest
64+
{
65+
if (! $this->storedRequest) {
66+
throw new \RuntimeException('No request has been registered yet.');
67+
}
68+
69+
return $this->storedRequest;
70+
}
71+
72+
public function registerResponse(SoapResponse $response)
73+
{
74+
$this->storedResponse = $response;
75+
}
76+
77+
public function cleanUpTemporaryState()
78+
{
79+
$this->storedRequest = null;
80+
$this->storedResponse = null;
81+
}
82+
83+
public function __getLastRequest(): string
84+
{
85+
return $this->__last_request;
86+
}
87+
88+
public function __getLastResponse(): string
89+
{
90+
return $this->__last_response;
91+
}
2792
}

src/Driver/ExtSoap/ExtSoapDecoder.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodeDredd\Soap\Driver\ExtSoap;
6+
7+
use Phpro\SoapClient\Soap\Driver\ExtSoap\Generator\DummyMethodArgumentsGenerator;
8+
use Phpro\SoapClient\Soap\Engine\DecoderInterface;
9+
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;
10+
11+
class ExtSoapDecoder implements DecoderInterface
12+
{
13+
/**
14+
* @var AbusedClient
15+
*/
16+
private $client;
17+
18+
/**
19+
* @var DummyMethodArgumentsGenerator
20+
*/
21+
private $argumentsGenerator;
22+
23+
public function __construct(AbusedClient $client, DummyMethodArgumentsGenerator $argumentsGenerator)
24+
{
25+
$this->client = $client;
26+
$this->argumentsGenerator = $argumentsGenerator;
27+
}
28+
29+
public function decode(string $method, SoapResponse $response)
30+
{
31+
$this->client->registerResponse($response);
32+
try {
33+
$decoded = $this->client->__soapCall($method, $this->argumentsGenerator->generateForSoapCall($method));
34+
} finally {
35+
$this->client->cleanUpTemporaryState();
36+
}
37+
38+
return $decoded;
39+
}
40+
}

src/Driver/ExtSoap/ExtSoapDriver.php

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,89 @@
22

33
namespace CodeDredd\Soap\Driver\ExtSoap;
44

5-
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapDriver as PhproExtSoapDriver;
65
use Phpro\SoapClient\Soap\Driver\ExtSoap\ExtSoapOptions;
6+
use Phpro\SoapClient\Soap\Driver\ExtSoap\Generator\DummyMethodArgumentsGenerator;
7+
use Phpro\SoapClient\Soap\Engine\DecoderInterface;
8+
use Phpro\SoapClient\Soap\Engine\DriverInterface;
9+
use Phpro\SoapClient\Soap\Engine\EncoderInterface;
10+
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataFactory;
11+
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataInterface;
12+
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;
13+
use Phpro\SoapClient\Soap\HttpBinding\SoapResponse;
714

8-
class ExtSoapDriver extends PhproExtSoapDriver
15+
class ExtSoapDriver implements DriverInterface
916
{
10-
public static function createFromOptions(ExtSoapOptions $options): PhproExtSoapDriver
17+
/**
18+
* @var AbusedClient
19+
*/
20+
private $client;
21+
22+
/**
23+
* @var EncoderInterface
24+
*/
25+
private $encoder;
26+
27+
/**
28+
* @var DecoderInterface
29+
*/
30+
private $decoder;
31+
32+
/**
33+
* @var MetadataInterface
34+
*/
35+
private $metadata;
36+
37+
public function __construct(
38+
AbusedClient $client,
39+
EncoderInterface $encoder,
40+
DecoderInterface $decoder,
41+
MetadataInterface $metadata
42+
) {
43+
$this->client = $client;
44+
$this->encoder = $encoder;
45+
$this->decoder = $decoder;
46+
$this->metadata = $metadata;
47+
}
48+
49+
public static function createFromOptions(ExtSoapOptions $options): self
1150
{
1251
$client = AbusedClient::createFromOptions($options);
1352

14-
return self::createFromClient($client);
53+
return self::createFromClient(
54+
$client,
55+
MetadataFactory::manipulated(new ExtSoapMetadata($client), $options->getMetadataOptions())
56+
);
57+
}
58+
59+
public static function createFromClient(AbusedClient $client, MetadataInterface $metadata = null): self
60+
{
61+
$metadata = $metadata ?? MetadataFactory::lazy(new ExtSoapMetadata($client));
62+
63+
return new self(
64+
$client,
65+
new ExtSoapEncoder($client),
66+
new ExtSoapDecoder($client, new DummyMethodArgumentsGenerator($metadata)),
67+
$metadata
68+
);
69+
}
70+
71+
public function decode(string $method, SoapResponse $response)
72+
{
73+
return $this->decoder->decode($method, $response);
74+
}
75+
76+
public function encode(string $method, array $arguments): SoapRequest
77+
{
78+
return $this->encoder->encode($method, $arguments);
79+
}
80+
81+
public function getMetadata(): MetadataInterface
82+
{
83+
return $this->metadata;
84+
}
85+
86+
public function getClient(): AbusedClient
87+
{
88+
return $this->client;
1589
}
1690
}

src/Driver/ExtSoap/ExtSoapEncoder.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodeDredd\Soap\Driver\ExtSoap;
6+
7+
use Phpro\SoapClient\Soap\Engine\EncoderInterface;
8+
use Phpro\SoapClient\Soap\HttpBinding\SoapRequest;
9+
10+
class ExtSoapEncoder implements EncoderInterface
11+
{
12+
/**
13+
* @var AbusedClient
14+
*/
15+
private $client;
16+
17+
public function __construct(AbusedClient $client)
18+
{
19+
$this->client = $client;
20+
}
21+
22+
public function encode(string $method, array $arguments): SoapRequest
23+
{
24+
try {
25+
$this->client->__soapCall($method, $arguments);
26+
$encoded = $this->client->collectRequest();
27+
} finally {
28+
$this->client->cleanUpTemporaryState();
29+
}
30+
31+
return $encoded;
32+
}
33+
}

src/Driver/ExtSoap/ExtSoapEngineFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ public static function fromOptionsWithHandler(
1818
) {
1919
$driver = ExtSoapDriver::createFromOptions($options);
2020

21-
return $withMocking ? new EngineFaker($driver, $handler, $options->getWsdl()) : new Engine($driver, $handler);
21+
return $withMocking ? new EngineFaker($driver, $handler, $options) : new Engine($driver, $handler);
2222
}
2323
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodeDredd\Soap\Driver\ExtSoap;
6+
7+
use CodeDredd\Soap\Driver\ExtSoap\Metadata\MethodsParser;
8+
use CodeDredd\Soap\Driver\ExtSoap\Metadata\TypesParser;
9+
use CodeDredd\Soap\Driver\ExtSoap\Metadata\XsdTypesParser;
10+
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\MethodCollection;
11+
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\TypeCollection;
12+
use Phpro\SoapClient\Soap\Engine\Metadata\Collection\XsdTypeCollection;
13+
use Phpro\SoapClient\Soap\Engine\Metadata\MetadataInterface;
14+
15+
class ExtSoapMetadata implements MetadataInterface
16+
{
17+
/**
18+
* @var AbusedClient
19+
*/
20+
private $abusedClient;
21+
22+
/**
23+
* @var XsdTypeCollection|null
24+
*/
25+
private $xsdTypes;
26+
27+
public function __construct(AbusedClient $abusedClient)
28+
{
29+
$this->abusedClient = $abusedClient;
30+
}
31+
32+
public function getMethods(): MethodCollection
33+
{
34+
return (new MethodsParser($this->getXsdTypes()))->parse($this->abusedClient);
35+
}
36+
37+
public function getTypes(): TypeCollection
38+
{
39+
return (new TypesParser($this->getXsdTypes()))->parse($this->abusedClient);
40+
}
41+
42+
private function getXsdTypes(): XsdTypeCollection
43+
{
44+
if (null === $this->xsdTypes) {
45+
$this->xsdTypes = XsdTypesParser::default()->parse($this->abusedClient);
46+
}
47+
48+
return $this->xsdTypes;
49+
}
50+
}

0 commit comments

Comments
 (0)