Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for named params in route() method #9

Merged
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
50 changes: 33 additions & 17 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Leaf Router
* ---------------
* Super simple and powerful routing with Leaf
*
*
* @author Michael Darko
* @since 1.2.0
* @version 3.0
Expand Down Expand Up @@ -83,7 +83,7 @@ public static function mount(string $path, $handler)

/**
* Alias for mount
*
*
* @param string $path The route sub pattern/path to mount the callbacks on
* @param callable|array $handler The callback method
*/
Expand All @@ -96,7 +96,7 @@ public static function group(string $path, $handler)

/**
* Store a route and it's handler
*
*
* @param string $methods Allowed HTTP methods (separated by `|`)
* @param string $pattern The route pattern/path to match
* @param string|array|callable $handler The handler for route when matched
Expand Down Expand Up @@ -156,7 +156,7 @@ public static function match(string $methods, string $pattern, $handler)

/**
* Add a route with all available HTTP methods
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -171,7 +171,7 @@ public static function all(string $pattern, $handler)

/**
* Add a route with GET method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -182,7 +182,7 @@ public static function get(string $pattern, $handler)

/**
* Add a route with POST method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -193,7 +193,7 @@ public static function post(string $pattern, $handler)

/**
* Add a route with PUT method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -204,7 +204,7 @@ public static function put(string $pattern, $handler)

/**
* Add a route with PATCH method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -215,7 +215,7 @@ public static function patch(string $pattern, $handler)

/**
* Add a route with OPTIONS method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand All @@ -226,7 +226,7 @@ public static function options(string $pattern, $handler)

/**
* Add a route with DELETE method
*
*
* @param string $pattern The route pattern/path to match
* @param string|array|callable The handler for route when matched
*/
Expand Down Expand Up @@ -254,7 +254,7 @@ public static function redirect(

/**
* Create a resource route for using controllers.
*
*
* This creates a routes that implement CRUD functionality in a controller
* `/posts` creates:
* - `/posts` - GET | HEAD - Controller@index
Expand All @@ -264,7 +264,7 @@ public static function redirect(
* - `/posts/{id}/edit` - GET | HEAD - Controller@edit
* - `/posts/{id}/edit` - POST | PUT | PATCH - Controller@update
* - `/posts/{id}/delete` - POST | DELETE - Controller@destroy
*
*
* @param string $pattern The base route to use eg: /post
* @param string $controller to handle route eg: PostController
*/
Expand All @@ -281,15 +281,15 @@ public static function resource(string $pattern, string $controller)

/**
* Create a resource route for using controllers without the create and edit actions.
*
*
* This creates a routes that implement CRUD functionality in a controller
* `/posts` creates:
* - `/posts` - GET | HEAD - Controller@index
* - `/posts` - POST - Controller@store
* - `/posts/{id}` - GET | HEAD - Controller@show
* - `/posts/{id}/edit` - POST | PUT | PATCH - Controller@update
* - `/posts/{id}/delete` - POST | DELETE - Controller@destroy
*
*
* @param string $pattern The base route to use eg: /post
* @param string $controller to handle route eg: PostController
*/
Expand All @@ -304,7 +304,7 @@ public static function apiResource(string $pattern, string $controller)

/**
* Redirect to another route
*
*
* @param string|array $route The route to redirect to
* @param array|null $data Data to pass to the next route
*/
Expand Down Expand Up @@ -335,15 +335,31 @@ public static function push($route, ?array $data = null)
* Get route url by defined route name
*
* @param string $routeName
* @param array|string|null $params
*
* @return string
*/
public static function route(string $routeName): string
public static function route(string $routeName, $params = null): string
{
if (!isset(static::$namedRoutes[$routeName])) {
trigger_error('Route named ' . $routeName . ' not found');
}

return static::$namedRoutes[$routeName];
$routePath = static::$namedRoutes[$routeName];
if ($params) {
if (is_array($params)) {
foreach ($params as $key => $value) {
if (!preg_match('/{('. $key .')}/', $routePath)) {
trigger_error('Param "' . $key . '" not found in route "' . static::$namedRoutes[$routeName] . '"');
}
$routePath = str_replace('{' . $key . '}', $value, $routePath);
}
}
if (is_string($params)) {
$routePath = preg_replace('/{(.*?)}/', $params, $routePath);
}
}

return $routePath;
}
}
26 changes: 26 additions & 0 deletions tests/routes.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,34 @@ class TRoute
expect($routeUrl)->toBe('/route/url');
});

test('route should return url with replaced named params using params as array', function () {
$router = new Router;
$router->match('GET', '/movies/{movieId}/photos/{photoId}', ['handler', 'name' => 'route-name']);

$routeUrl = $router->route('route-name', ['movieId' => 'my-movie', 'photoId' => 'my-photo']);

expect($routeUrl)->toBe('/movies/my-movie/photos/my-photo');
});

test('route should return url with replaced named params using params as string', function () {
$router = new Router;
$router->match('GET', '/movies/{movieId}/edit', ['handler', 'name' => 'route-name']);

$routeUrl = $router->route('route-name', 'my-movie');

expect($routeUrl)->toBe('/movies/my-movie/edit');
});

test('route should throw exception if no route found for name', function () {
$router = new Router;

expect(fn() => $router->route('non-existent-route-name'))->toThrow(Exception::class);
});

test('route should throw error if no named param found for params array', function () {
$router = new Router;
$router->match('GET', '/movies/{movieId}/photos/{photoId}', ['handler', 'name' => 'route-name']);

expect(fn() => $router->route('route-name', ['movieId' => 'my-movie', 'otherId' => 'my-photo', 'someOtherId' => 'my-music']))
->toThrow(Exception::class, 'Param "otherId" not found in route "/movies/{movieId}/photos/{photoId}"');
});
Loading