Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 7e0b635

Browse files
committed
Created alternate ServerUrl helper
- Consumes PSR-7 request URI.
1 parent ce4c9a1 commit 7e0b635

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
/**
3+
* @see http://github.com/zendframework/zend-expressive for the canonical source repository
4+
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
5+
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
namespace Zend\Expressive\Template\ZendView;
9+
10+
use Psr\Http\Message\UriInterface;
11+
use Zend\View\Helper\AbstractHelper;
12+
13+
/**
14+
* Alternate ServerUrl helper for use in Expressive.
15+
*/
16+
class ServerUrlHelper extends AbstractHelper
17+
{
18+
/**
19+
* @var UriInterface
20+
*/
21+
private $uri;
22+
23+
/**
24+
* Return a path relative to the current request URI.
25+
*
26+
* If no request URI has been injected, it returns an absolute path
27+
* only; relative paths are made absolute, and absolute paths are returned
28+
* verbatim (null paths are returned as root paths).
29+
*
30+
* Otherwise, returns a fully-qualified URI based on the injected request
31+
* URI; absolute paths replace the request URI path, while relative paths
32+
* are appended to it (and null paths are considered the current path).
33+
*
34+
* The $path may optionally contain the query string and/or fragment to
35+
* use.
36+
*
37+
* @param null|string $path
38+
* @return string
39+
*/
40+
public function __invoke($path = null)
41+
{
42+
if ($this->uri instanceof UriInterface) {
43+
return $this->createUrlFromUri($path);
44+
}
45+
46+
if (empty($path)) {
47+
return '/';
48+
}
49+
50+
if ('/' === $path[0]) {
51+
return $path;
52+
}
53+
54+
return '/' . $path;
55+
}
56+
57+
/**
58+
* @param UriInterface $uri
59+
*/
60+
public function setUri(UriInterface $uri)
61+
{
62+
$this->uri = $uri;
63+
}
64+
65+
/**
66+
* @param string $specification
67+
* @return string
68+
*/
69+
private function createUrlFromUri($specification)
70+
{
71+
preg_match('%^(?P<path>[^?#]*)(?:(?:\?(?P<query>[^#]*))?(?:\#(?P<fragment>.*))?)$%', (string) $specification, $matches);
72+
$path = $matches['path'];
73+
$query = isset($matches['query']) ? $matches['query'] : '';
74+
$fragment = isset($matches['fragment']) ? $matches['fragment'] : '';
75+
76+
$uri = $this->uri
77+
->withQuery('')
78+
->withFragment('');
79+
80+
// Relative path
81+
if (! empty($path) && '/' !== $path[0]) {
82+
$path = rtrim($this->uri->getPath(), '/') . '/' . $path;
83+
}
84+
85+
// Path present; set on URI
86+
if (! empty($path)) {
87+
$uri = $uri->withPath($path);
88+
}
89+
90+
// Query present; set on URI
91+
if (! empty($query)) {
92+
$uri = $uri->withQuery($query);
93+
}
94+
95+
// Fragment present; set on URI
96+
if (! empty($fragment)) {
97+
$uri = $uri->withFragment($fragment);
98+
}
99+
100+
return (string) $uri;
101+
}
102+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
/**
3+
* Zend Framework (http://framework.zend.com/)
4+
*
5+
* @see https://github.com/zendframework/zend-expressive for the canonical source repository
6+
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
7+
* @license https://github.com/zendframework/zend-expressive/blob/master/LICENSE.md New BSD License
8+
*/
9+
10+
namespace ZendTest\Expressive\Template\ZendView;
11+
12+
use PHPUnit_Framework_TestCase as TestCase;
13+
use Psr\Http\Message\UriInterface;
14+
use Zend\Diactoros\Uri;
15+
use Zend\Expressive\Template\ZendView\ServerUrlHelper;
16+
17+
class ServerUrlHelperTest extends TestCase
18+
{
19+
public function plainPaths()
20+
{
21+
// @codingStandardsIgnoreStart
22+
return [
23+
'null' => [null, '/'],
24+
'empty' => ['', '/'],
25+
'root' => ['/', '/'],
26+
'relative-path' => ['foo/bar', '/foo/bar'],
27+
'abs-path' => ['/foo/bar', '/foo/bar'],
28+
];
29+
// @codingStandardsIgnoreEnd
30+
}
31+
32+
/**
33+
* @dataProvider plainPaths
34+
*/
35+
public function testInvocationReturnsPathOnlyIfNoUriInjected($path, $expected)
36+
{
37+
$helper = new ServerUrlHelper();
38+
$this->assertEquals($expected, $helper($path));
39+
}
40+
41+
public function plainPathsForUseWithUri()
42+
{
43+
$uri = new Uri('https://example.com/resource');
44+
// @codingStandardsIgnoreStart
45+
return [
46+
'null' => [$uri, null, 'https://example.com/resource'],
47+
'empty' => [$uri, '', 'https://example.com/resource'],
48+
'root' => [$uri, '/', 'https://example.com/'],
49+
'relative-path' => [$uri, 'foo/bar', 'https://example.com/resource/foo/bar'],
50+
'abs-path' => [$uri, '/foo/bar', 'https://example.com/foo/bar'],
51+
];
52+
// @codingStandardsIgnoreEnd
53+
}
54+
55+
/**
56+
* @dataProvider plainPathsForUseWithUri
57+
*/
58+
public function testInvocationReturnsUriComposingPathWhenUriInjected(UriInterface $uri, $path, $expected)
59+
{
60+
$helper = new ServerUrlHelper();
61+
$helper->setUri($uri);
62+
$this->assertEquals((string) $expected, $helper($path));
63+
}
64+
65+
public function uriWithQueryString()
66+
{
67+
$uri = new Uri('https://example.com/resource?bar=baz');
68+
// @codingStandardsIgnoreStart
69+
return [
70+
'null' => [$uri, null, 'https://example.com/resource'],
71+
'empty' => [$uri, '', 'https://example.com/resource'],
72+
'root' => [$uri, '/', 'https://example.com/'],
73+
'relative-path' => [$uri, 'foo/bar', 'https://example.com/resource/foo/bar'],
74+
'abs-path' => [$uri, '/foo/bar', 'https://example.com/foo/bar'],
75+
];
76+
// @codingStandardsIgnoreEnd
77+
}
78+
79+
/**
80+
* @dataProvider uriWithQueryString
81+
*/
82+
public function testStripsQueryStringFromInjectedUri(UriInterface $uri, $path, $expected)
83+
{
84+
$helper = new ServerUrlHelper();
85+
$helper->setUri($uri);
86+
$this->assertEquals($expected, $helper($path));
87+
}
88+
89+
public function uriWithFragment()
90+
{
91+
$uri = new Uri('https://example.com/resource#bar');
92+
// @codingStandardsIgnoreStart
93+
return [
94+
'null' => [$uri, null, 'https://example.com/resource'],
95+
'empty' => [$uri, '', 'https://example.com/resource'],
96+
'root' => [$uri, '/', 'https://example.com/'],
97+
'relative-path' => [$uri, 'foo/bar', 'https://example.com/resource/foo/bar'],
98+
'abs-path' => [$uri, '/foo/bar', 'https://example.com/foo/bar'],
99+
];
100+
// @codingStandardsIgnoreEnd
101+
}
102+
103+
/**
104+
* @dataProvider uriWithFragment
105+
*/
106+
public function testStripsFragmentFromInjectedUri(UriInterface $uri, $path, $expected)
107+
{
108+
$helper = new ServerUrlHelper();
109+
$helper->setUri($uri);
110+
$this->assertEquals($expected, $helper($path));
111+
}
112+
113+
public function pathsWithQueryString()
114+
{
115+
$uri = new Uri('https://example.com/resource');
116+
// @codingStandardsIgnoreStart
117+
return [
118+
'empty-path' => [$uri, '?foo=bar', 'https://example.com/resource?foo=bar'],
119+
'root-path' => [$uri, '/?foo=bar', 'https://example.com/?foo=bar'],
120+
'relative-path' => [$uri, 'foo/bar?foo=bar', 'https://example.com/resource/foo/bar?foo=bar'],
121+
'abs-path' => [$uri, '/foo/bar?foo=bar', 'https://example.com/foo/bar?foo=bar'],
122+
];
123+
// @codingStandardsIgnoreEnd
124+
}
125+
126+
/**
127+
* @dataProvider pathsWithQueryString
128+
*/
129+
public function testUsesQueryStringFromProvidedPath(UriInterface $uri, $path, $expected)
130+
{
131+
$helper = new ServerUrlHelper();
132+
$helper->setUri($uri);
133+
$this->assertEquals($expected, $helper($path));
134+
}
135+
136+
public function pathsWithFragment()
137+
{
138+
$uri = new Uri('https://example.com/resource');
139+
// @codingStandardsIgnoreStart
140+
return [
141+
'empty-path' => [$uri, '#bar', 'https://example.com/resource#bar'],
142+
'root-path' => [$uri, '/#bar', 'https://example.com/#bar'],
143+
'relative-path' => [$uri, 'foo/bar#bar', 'https://example.com/resource/foo/bar#bar'],
144+
'abs-path' => [$uri, '/foo/bar#bar', 'https://example.com/foo/bar#bar'],
145+
];
146+
// @codingStandardsIgnoreEnd
147+
}
148+
149+
/**
150+
* @dataProvider pathsWithFragment
151+
*/
152+
public function testUsesFragmentFromProvidedPath(UriInterface $uri, $path, $expected)
153+
{
154+
$helper = new ServerUrlHelper();
155+
$helper->setUri($uri);
156+
$this->assertEquals($expected, $helper($path));
157+
}
158+
}

0 commit comments

Comments
 (0)