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
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ See [`Sender`](#sender) for more details.

#### withBase()

The `withBase($baseUri)` method can be used to change the base URI used to
The `withBase($baseUri, array $parameters = array())` method can be used to change the base URI used to
resolve relative URIs to.

```php
Expand Down Expand Up @@ -165,8 +165,10 @@ See also [`withBase()`](#withbase).

#### resolve()

The `resolve($uri)` method can be used to resolve the given relative URI to
The `resolve($uri, array $parameters = array())` method can be used to resolve the given relative URI to
an absolute URI by appending it behind the configured base URI.
It also replaces URI template placerholders with the given `$parameters`
according to [RFC 6570](http://tools.ietf.org/html/rfc6570).
It returns a new [`Uri`](#uri) instace which can then be passed
to the [HTTP methods](#methods).

Expand All @@ -182,6 +184,31 @@ echo $newBrowser->resolve('/example');
// http://api.example.com/v3/example
```

The given URI may also contain URI template placeholders:

```php
echo $browser->resolve('http://example.com/{?first,second,third}', array(
'first' => 'a',
'third' => 'c'
));
// http://example.com/?first=a&third=c
```

The URI template placeholders can also be combined with a base URI like this:

```php
echo $newBrowser->resolve('/fetch{/file}{?version,tag}', array(
'file' => 'example',
'version' => 1.0,
'tag' => 'just testing'
));
// http://api.example.com/v3/fetch/file?version=1.0&tag=just%20testing
```

This uses the excellent [rize/uri-template](https://github.com/rize/UriTemplate) library under the hood.
Please refer to [its documentation](https://github.com/rize/UriTemplate#usage) or
[RFC 6570](http://tools.ietf.org/html/rfc6570) for more details.

Trying to resolve anything that does not live under the same base URI will
result in an `UnexpectedValueException`:

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"react/http-client": "0.3.*|0.4.*",
"react/socket-client": "0.3.*|0.4.*",
"react/dns": "0.3.*|0.4.*",
"react/promise": "1.*|2.*"
"react/promise": "1.*|2.*",
"rize/uri-template": "~0.3.0"
}
}
18 changes: 13 additions & 5 deletions src/Browser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
use Clue\React\Buzz\Message\Headers;
use Clue\React\Buzz\Io\Sender;
use Clue\React\Buzz\Message\Uri;
use Rize\UriTemplate;

class Browser
{
private $sender;
private $loop;
private $uriTemplate;
private $baseUri = null;
private $options = array();

Expand All @@ -24,6 +26,7 @@ public function __construct(LoopInterface $loop, Sender $sender = null)
}
$this->sender = $sender;
$this->loop = $loop;
$this->uriTemplate = new UriTemplate();
}

public function get($url, $headers = array())
Expand Down Expand Up @@ -74,35 +77,40 @@ public function send(Request $request)
/**
* Returns an absolute URI by processing the given relative URI
*
* @param string|Uri $uri relative or absolute URI
* @param string|Uri $uri relative or absolute URI
* @param array $parameters parameters for URI template syntax (RFC 6570)
* @return Uri absolute URI
* @see self::withBase()
*/
public function resolve($uri)
public function resolve($uri, $parameters = array())
{
if ($this->baseUri !== null) {
return $this->baseUri->expandBase($uri);
$uri = $this->baseUri->expandBase($uri);
}

$uri = $this->uriTemplate->expand($uri, $parameters);

return new Uri($uri);
}

/**
* Creates a new Browser instance with the given absolute base URI
* Creates a new Browser instance with the given absolute base URI, possibly using URI template syntax (RFC 6570)
*
* This is mostly useful for use with the `resolve()` method.
* Any relative URI passed to `uri()` will simply be appended behind the given
* `$baseUrl`.
*
* @param string|Uri $baseUri absolute base URI
* @param array $parameters (optional) default parameters to pass to URI template placeholders
* @return self
* @see self::url()
* @see self::withoutBase()
*/
public function withBase($baseUri)
public function withBase($baseUri, array $parameters = array())
{
$browser = clone $this;
$browser->baseUri = new Uri($baseUri);
$browser->uriTemplate = new UriTemplate('', $parameters);

return $browser;
}
Expand Down
57 changes: 57 additions & 0 deletions tests/BrowserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,61 @@ public function testResolveEmptyReturnsBase(Browser $browser)
{
$this->assertEquals('http://example.com/root', $browser->resolve(''));
}

/**
* @depends testWithBase
* @param Browser $browser
*/
public function testResolveUriTemplateWithBase(Browser $browser)
{
$this->assertEquals('http://example.com/root/?q=test', $browser->resolve('/{?q}', array('q' => 'test')));
}

public function testResolveUriTemplateAbsolute()
{
$this->assertEquals('http://example.com/?q=test', $this->browser->resolve('http://example.com/{?q}', array('q' => 'test')));
}

public function testWithBaseUriTemplateParameters()
{
$browser = $this->browser->withBase('http://example.com/{version}/', array('version' => 1));

return $browser;
}

/**
* @depends testWithBaseUriTemplateParameters
* @param Browser $browser
*/
public function testResolveUriTemplateWithDefaultParameters(Browser $browser)
{
$this->assertEquals('http://example.com/1/', $browser->resolve(''));
}

/**
* @depends testWithBaseUriTemplateParameters
* @param Browser $browser
*/
public function testResolveUriTemplateOverwriteDefaultParameter(Browser $browser)
{
$this->assertEquals('http://example.com/2/', $browser->resolve('', array('version' => 2)));
}

/**
* @depends testWithBaseUriTemplateParameters
* @param Browser $browser
*/
public function testResolveUriTemplateUnsetQueryParameter(Browser $browser)
{
$this->assertEquals('http://example.com/1/test', $browser->resolve('/test{?q}'));
}

/**
* @depends testWithBaseUriTemplateParameters
* @param Browser $browser
*/
public function testResolveUriTemplateSetQueryParameter(Browser $browser)
{
$this->assertEquals('http://example.com/1/test?q=hi', $browser->resolve('/test{?q}', array('q' => 'hi')));
}
}