Skip to content

Commit dc2b01c

Browse files
committed
add URL pattern template replacement function, per #3
1 parent 0ce044c commit dc2b01c

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

src/UrlHelper.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,30 @@ protected function slug($value, $max_length = null) {
7171

7272
return substr($clean, 0, $max_length ?: $this->slug_max_length);
7373
}
74+
75+
/**
76+
* Replaces a route template, with placeholders such as "<foo>" or "<foo:bar>", with
77+
* a set of replacement values.
78+
*
79+
* @param string $template route template
80+
* @param array $values map where token name => replacement value
81+
*
82+
* @return string
83+
*/
84+
protected function replace($template, $values)
85+
{
86+
return preg_replace_callback(
87+
Router::PARAM_PATTERN,
88+
function ($matches) use ($values) {
89+
$name = $matches[1];
90+
91+
if (!isset($values[$name])) {
92+
throw new InvalidArgumentException("missing replacement value for token: {$name}");
93+
}
94+
95+
return $values[$name];
96+
},
97+
$template
98+
);
99+
}
74100
}

test/test.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ public function test($input, $expected)
2222
}
2323
}
2424

25+
class ReplaceTester extends UrlHelper
26+
{
27+
/**
28+
* @param string $template
29+
* @param array $tokens
30+
* @param string $expected
31+
*
32+
* @return string
33+
*/
34+
public function test($template, $tokens, $expected)
35+
{
36+
eq($this->replace($template, $tokens), $expected);
37+
}
38+
}
39+
2540
class SampleUrlHelper extends UrlHelper
2641
{
2742
/**
@@ -40,7 +55,7 @@ class SampleController implements Controller
4055
{
4156
public function run($id, $title)
4257
{
43-
return array($id, $title);
58+
return [$id, $title];
4459
}
4560
}
4661

@@ -168,7 +183,7 @@ function () {
168183
function () use ($router) {
169184
$router->resolve('GET', '/users/bob?crazy-yo');
170185
},
171-
'#^'.preg_quote('unexpected query string in $url: /users/bob?crazy-yo').'$#'
186+
'#^' . preg_quote('unexpected query string in $url: /users/bob?crazy-yo') . '$#'
172187
);
173188
}
174189
);
@@ -331,6 +346,28 @@ function () use ($url) {
331346
}
332347
);
333348

349+
test(
350+
'can replace tokens in templates',
351+
function () {
352+
$replace = new ReplaceTester();
353+
354+
$replace->test('foo/<bar>', ['bar' => 'hello'], 'foo/hello');
355+
356+
$replace->test('foo/<bar:slug>', ['bar' => 'hello'], 'foo/hello');
357+
358+
$replace->test('foo/<bar:slug>/<baz:\w+>', ['bar' => 'hello', 'baz' => 'world'], 'foo/hello/world');
359+
360+
expect(
361+
'InvalidArgumentException',
362+
'should throw for missing replacements token',
363+
function () use ($replace) {
364+
$replace->test('foo/<bar>/<baz>', ['bar' => 'hello'], 'foo/hello/');
365+
},
366+
'/for token: baz/'
367+
);
368+
}
369+
);
370+
334371
test(
335372
'can use wildcard in patterns',
336373
function () {

0 commit comments

Comments
 (0)