Skip to content
Merged
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
65 changes: 28 additions & 37 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -749,44 +749,37 @@ public static function findRoute(
$uri = $uri ?? static::getCurrentUri();
$routes = $routes ?? static::$routes[\Leaf\Http\Request::getMethod()];

foreach ($routes as $route) {
// Replace all curly braces matches {} into word patterns (like Laravel)
$route['pattern'] = preg_replace('/\/{(.*?)}/', '/(.*?)', $route['pattern']);

// we have a match!
if (preg_match_all('#^' . $route['pattern'] . '$#', $uri, $matches, PREG_OFFSET_CAPTURE)) {
// Rework matches to only contain the matches, not the orig string
$matches = array_slice($matches, 1);

// Extract the matched URL parameters (and only the parameters)
$params = array_map(function ($match, $index) use ($matches) {
// We have a following parameter: take the substring from the current param position until the next one's position (thank you PREG_OFFSET_CAPTURE)
if (isset($matches[$index + 1]) && isset($matches[$index + 1][0]) && $matches[$index + 1][0][1] != -1 && is_array($matches[$index + 1][0])) {
return trim(substr($match[0][0], 0, $matches[$index + 1][0][1] - $match[0][1]), '/');
}

// Temporary fix for optional parameters
if (($match[0][1] ?? 1) === -1 && ($match[0][0] ?? null) === '') {
return;
}

// We have no following parameters: return the whole lot
return isset($match[0][0]) ? trim($match[0][0], '/') : null;
}, $matches, array_keys($matches));
// Preserve existing $_GET parameters
$existingQueryParams = $_GET;

$paramsWithSlash = array_filter($params, function ($param) {
if (!$param) {
return false;
}

return strpos($param, '/') !== false;
});
// Extract query string and remove it from URI
$parsedUrl = parse_url($uri);
$uriPath = $parsedUrl['path'] ?? '/';
parse_str($parsedUrl['query'] ?? '', $queryParams);

// if any of the params contain /, we should skip this route
if (!empty($paramsWithSlash)) {
continue;
foreach ($routes as $route) {
// Match named parameters in the pattern
preg_match_all('/{(\w+)}/', $route['pattern'], $paramNames);
$paramNames = $paramNames[1] ?? [];

// Replace all curly braces {} with regex capture groups
$pattern = preg_replace('/\/{(.*?)}/', '/([^\/]+)', $route['pattern']);

// Match current URI against the route pattern
if (preg_match('#^' . $pattern . '$#', $uriPath, $matches)) {
array_shift($matches); // Remove full match

// Extract parameter values
$params = [];
foreach ($matches as $index => $value) {
$paramName = $paramNames[$index] ?? "var" . ($index + 1);
$params[$paramName] = trim($value, '/');
}

// Merge extracted route parameters with existing query parameters
$_GET = array_merge($existingQueryParams, $params);

// Return matched route info
$routeData = [
'params' => $params,
'handler' => $route['handler'],
Expand All @@ -795,9 +788,7 @@ public static function findRoute(

$handledRoutes[] = $routeData;

if ($returnFirst) {
break;
}
if ($returnFirst) break;
}
}

Expand Down