Add SEO-friendly URL handling in router.php

Introduced a `handleSeoUrls` method to support SEO-friendly URLs by transforming them into standard routing. Added validation for slugs, IDs, and potential actions to ensure proper parsing and prevent conflicts with existing routes. Enhanced overall routing functionality to support framework-wide SEO optimizations.
This commit is contained in:
stephan.kasdorf
2025-08-20 11:39:27 +02:00
parent 157016ff35
commit 197cab3691

View File

@@ -150,8 +150,14 @@ class Router extends Config
$params = false; $params = false;
$param_parts = explode('?', $_SERVER["REQUEST_URI"]); $param_parts = explode('?', $_SERVER["REQUEST_URI"]);
$uri_parts = explode('/', $param_parts[0]); $uri_parts = explode('/', $param_parts[0]);
if(is_array($uri_parts)) if(is_array($uri_parts))
{ {
if (self::handleSeoUrls($uri_parts))
{
// SEO URL was handled, skip normal processing
return;
}
if($uri_parts[1] == "") if($uri_parts[1] == "")
{ {
self::$_cur_page = "index"; self::$_cur_page = "index";
@@ -263,6 +269,65 @@ class Router extends Config
return self::getCurPage(); return self::getCurPage();
} }
/**
* @desc Generic SEO URL handler for framework-wide SEO-friendly URLs
* @param array $uri_parts The URI parts from the request
* @return bool Returns true if SEO URL was handled, false otherwise
*/
private static function handleSeoUrls($uri_parts)
{
// Check if we have the minimum required parts for SEO URL: /controller/slug/id
if (!is_array($uri_parts) || count($uri_parts) < 4)
{
return false;
}
// Extract components
$controller = $uri_parts[1] ?? '';
$slug = $uri_parts[2] ?? '';
$possibleId = $uri_parts[3] ?? '';
// Validate that the last part is numeric (ID)
if (!is_numeric($possibleId))
{
return false;
}
// Validate that the slug contains non-numeric characters (to differentiate from traditional URLs)
if (is_numeric($slug))
{
return false;
}
// Validate that the slug is not an existing action name
if (self::isExistingAction($controller, $slug))
{
return false;
}
// SEO URL detected - transform it to standard routing
self::$_cur_page = $controller;
self::setAction('detail'); // Default action for SEO URLs
$_REQUEST['id'] = $possibleId;
$_REQUEST['slug'] = $slug; // Preserve slug for potential use in controllers
return true;
}
/**
* @desc Check if a slug matches an existing controller action
* @param string $controller The controller name
* @param string $slug The potential action/slug
* @return bool Returns true if it's an existing action
*/
private static function isExistingAction($controller, $slug)
{
// List of common actions that should not be treated as SEO slugs
$commonActions = ['detail', 'list', 'edit', 'delete', 'create', 'update', 'page', 'navigation', 'requestForm'];
return in_array($slug, $commonActions, true);
}
public static function RouterDebug($value) public static function RouterDebug($value)
{ {
if(is_array($value)) if(is_array($value))