diff --git a/README.md b/README.md index cb69a09..3d1f451 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ This project provides a *simple* API for invoking *async* RPCs to remote web ser * [getFunctions()](#getfunctions) * [getTypes()](#gettypes) * [getLocation()](#getlocation) + * [withLocation()](#withlocation) * [Proxy](#proxy) * [Functions](#functions) * [Promises](#promises) @@ -270,10 +271,29 @@ assert('http://example.com/soap/service' === $client->getLocation(0)); ``` When the `location` option has been set in the `Client` constructor -(such as when in non-WSDL mode), this method returns the value of the -given `location` option. +(such as when in non-WSDL mode) or via the `withLocation()` method, this +method returns the value of the given location. -Passing a `$function` not defined in the WSDL file will throw a `SoapFault`. +Passing a `$function` not defined in the WSDL file will throw a `SoapFault`. + +#### withLocation() + +The `withLocation(string $location): self` method can be used to +return a new `Client` with the updated location (URI) for all functions. + +Note that this is not to be confused with the WSDL file location. +A WSDL file can contain any number of function definitions. +It's very common that all of these functions use the same location definition. +However, technically each function can potentially use a different location. + +```php +$client = $client->withLocation('http://example.com/soap'); + +assert('http://example.com/soap' === $client->getLocation('echo')); +``` + +As an alternative to this method, you can also set the `location` option +in the `Client` constructor (such as when in non-WSDL mode). ### Proxy diff --git a/src/Client.php b/src/Client.php index ad9777b..85ee7af 100644 --- a/src/Client.php +++ b/src/Client.php @@ -268,8 +268,8 @@ public function getTypes() * ``` * * When the `location` option has been set in the `Client` constructor - * (such as when in non-WSDL mode), this method returns the value of the - * given `location` option. + * (such as when in non-WSDL mode) or via the `withLocation()` method, this + * method returns the value of the given location. * * Passing a `$function` not defined in the WSDL file will throw a `SoapFault`. * @@ -290,4 +290,34 @@ public function getLocation($function) // encode request for given $function return (string)$this->encoder->encode($function, array())->getUri(); } + + /** + * Returns a new `Client` with the updated location (URI) for all functions. + * + * Note that this is not to be confused with the WSDL file location. + * A WSDL file can contain any number of function definitions. + * It's very common that all of these functions use the same location definition. + * However, technically each function can potentially use a different location. + * + * ```php + * $client = $client->withLocation('http://example.com/soap'); + * + * assert('http://example.com/soap' === $client->getLocation('echo')); + * ``` + * + * As an alternative to this method, you can also set the `location` option + * in the `Client` constructor (such as when in non-WSDL mode). + * + * @param string $location + * @return self + * @see self::getLocation() + */ + public function withLocation($location) + { + $client = clone $this; + $client->encoder = clone $this->encoder; + $client->encoder->__setLocation($location); + + return $client; + } } diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index f694edb..7ee1a2f 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -227,4 +227,38 @@ public function testGetLocationWithExplicitLocationOptionReturnsAsIs() $this->assertEquals('http://example.com/', $this->client->getLocation(0)); } + + public function testWithLocationReturnsUpdatedClient() + { + $original = $this->client->getLocation(0); + $client = $this->client->withLocation('http://nonsense.invalid'); + + $this->assertEquals('http://nonsense.invalid', $client->getLocation(0)); + $this->assertEquals($original, $this->client->getLocation(0)); + } + + /** + * @expectedException RuntimeException + */ + public function testWithLocationInvalidRejectsWithRuntimeException() + { + $api = new Proxy($this->client->withLocation('http://nonsense.invalid')); + + $promise = $api->getBank(array('blz' => '12070000')); + + Block\await($promise, $this->loop); + } + + public function testWithLocationRestoredToOriginalResolves() + { + $original = $this->client->getLocation(0); + $client = $this->client->withLocation('http://nonsense.invalid'); + $client = $client->withLocation($original); + $api = new Proxy($client); + + $promise = $api->getBank(array('blz' => '12070000')); + + $result = Block\await($promise, $this->loop); + $this->assertInternalType('object', $result); + } }