Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ $client = new Client($browser, $wsdl, array(
));
```

You can use the `classmap` option to map certain WSDL types to PHP classes
like this:

```php
$client = new Client($browser, $wsdl, array(
'classmap' => array(
'getBankResponseType' => BankResponse::class
)
));
```

If you find an option is missing or not supported here, PRs are much
appreciated!

Expand Down
37 changes: 21 additions & 16 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@
* ));
* ```
*
* You can use the `classmap` option to map certain WSDL types to PHP classes
* like this:
*
* ```php
* $client = new Client($browser, $wsdl, array(
* 'classmap' => array(
* 'getBankResponseType' => BankResponse::class
* )
* ));
* ```
*
* If you find an option is missing or not supported here, PRs are much
* appreciated!
*
Expand All @@ -143,12 +154,11 @@ final class Client
*/
public function __construct(Browser $browser, $wsdlContents, array $options = array())
{
$wsdl = $wsdlContents !== null ? 'data://text/plain;base64,' . base64_encode($wsdlContents) : null;

$this->browser = $browser;
$this->encoder = new ClientEncoder(
$wsdlContents !== null ? 'data://text/plain;base64,' . base64_encode($wsdlContents) : null,
$options
);
$this->decoder = new ClientDecoder();
$this->encoder = new ClientEncoder($wsdl, $options);
$this->decoder = new ClientDecoder($wsdl, $options);
}

/**
Expand Down Expand Up @@ -180,8 +190,13 @@ public function soapCall($name, $args)
return $deferred->promise();
}

$decoder = $this->decoder;

return $this->browser->send($request)->then(
array($this, 'handleResponse')
function (ResponseInterface $response) use ($decoder, $name) {
// HTTP response received => decode results for this function call
return $decoder->decode($name, (string)$response->getBody());
}
);
}

Expand Down Expand Up @@ -262,14 +277,4 @@ public function getLocation($function)
// encode request for given $function
return (string)$this->encoder->encode($function, array())->getUri();
}

/**
* @param ResponseInterface $response
* @return mixed
* @internal
*/
public function handleResponse(ResponseInterface $response)
{
return $this->decoder->decode((string)$response->getBody());
}
}
20 changes: 8 additions & 12 deletions src/Protocol/ClientDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,24 @@ final class ClientDecoder extends SoapClient
{
private $response = null;

public function __construct()
{
// do not pass actual WSDL to parent constructor
// use faked non-wsdl-mode to let every method call pass through (pseudoCall)
parent::__construct(null, array('location' => '1', 'uri' => '2'));
}

/**
* Decodes the SOAP response / return value from the given SOAP envelope (HTTP response body)
*
* @param string $function
* @param string $response
* @return mixed
* @throws \SoapFault if response indicates a fault (error condition) or is invalid
*/
public function decode($response)
public function decode($function, $response)
{
// temporarily save response internally for further processing
// Temporarily save response internally for further processing
$this->response = $response;

// pretend we just invoked a SOAP function.
// internally, use the injected response to parse its results
$ret = $this->pseudoCall();
// Let's pretend we just invoked the given SOAP function.
// This won't actually invoke anything (see `__doRequest()`), but this
// requires a valid function name to match its definition in the WSDL.
// Internally, simply use the injected response to parse its results.
$ret = $this->__soapCall($function, array());
$this->response = null;

return $ret;
Expand Down
35 changes: 33 additions & 2 deletions tests/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
use Clue\React\Soap\Proxy;
use PHPUnit\Framework\TestCase;

class BankResponse
{
}

/**
* @group internet
*/
Expand Down Expand Up @@ -46,6 +50,30 @@ public function testBlzService()
$result = Block\await($promise, $this->loop);

$this->assertInternalType('object', $result);
$this->assertTrue(isset($result->details));
$this->assertTrue(isset($result->details->bic));
}

public function testBlzServiceWithClassmapReturnsExpectedType()
{
$this->client = new Client(new Browser($this->loop), self::$wsdl, array(
'classmap' => array(
'getBankResponseType' => 'BankResponse'
)
));

$this->assertCount(2, $this->client->getFunctions());
$this->assertCount(3, $this->client->getTypes());

$api = new Proxy($this->client);

$promise = $api->getBank(array('blz' => '12070000'));

$result = Block\await($promise, $this->loop);

$this->assertInstanceOf('BankResponse', $result);
$this->assertTrue(isset($result->details));
$this->assertTrue(isset($result->details->bic));
}

public function testBlzServiceWithSoapV12()
Expand All @@ -64,14 +92,15 @@ public function testBlzServiceWithSoapV12()
$result = Block\await($promise, $this->loop);

$this->assertInternalType('object', $result);
$this->assertTrue(isset($result->details));
$this->assertTrue(isset($result->details->bic));
}

public function testBlzServiceNonWsdlMode()
public function testBlzServiceNonWsdlModeReturnedWithoutOuterResultStructure()
{
$this->client = new Client(new Browser($this->loop), null, array(
'location' => 'http://www.thomas-bayer.com/axis2/services/BLZService',
'uri' => 'http://thomas-bayer.com/blz/',
'use' => SOAP_LITERAL
));

$api = new Proxy($this->client);
Expand All @@ -83,6 +112,8 @@ public function testBlzServiceNonWsdlMode()
$result = Block\await($promise, $this->loop);

$this->assertInternalType('object', $result);
$this->assertFalse(isset($result->details));
$this->assertTrue(isset($result->bic));
}

/**
Expand Down
23 changes: 21 additions & 2 deletions tests/Protocol/ClientDecoderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,26 @@ class ClientDecoderTest extends TestCase
*/
public function testDecodeThrowsSoapFaultForInvalidResponse()
{
$decoder = new ClientDecoder();
$decoder->decode('invalid');
$decoder = new ClientDecoder(null, array('location' => '1', 'uri' => '2'));
$decoder->decode('anything', 'invalid');
}

public function testDecodeMessageToObjectNonWsdl()
{
$decoder = new ClientDecoder(null, array('location' => '1', 'uri' => '2'));

$res = $decoder->decode('anything', <<<SOAP
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:getBankResponse xmlns:ns1="http://thomas-bayer.com/blz/"><ns1:details><ns1:bezeichnung>Deutsche Bank Ld Brandenburg</ns1:bezeichnung><ns1:bic>DEUTDEBB160</ns1:bic><ns1:ort>Potsdam</ns1:ort><ns1:plz>14405</ns1:plz></ns1:details></ns1:getBankResponse></soapenv:Body></soapenv:Envelope>
SOAP
);

$expected = new stdClass();
$expected->bezeichnung = 'Deutsche Bank Ld Brandenburg';
$expected->bic = 'DEUTDEBB160';
$expected->ort = 'Potsdam';
$expected->plz = '14405';

$this->assertEquals($expected, $res);
}
}