diff --git a/includes/class-link-filter.php b/includes/class-link-filter.php index d6a6872..f00c35b 100644 --- a/includes/class-link-filter.php +++ b/includes/class-link-filter.php @@ -32,7 +32,63 @@ final class LinkFilter public static function add_town_prefix(string $url): string { - // Implementation in Task 4. - return $url; + if (Helpers::is_bypassed()) { + return $url; + } + + $town = Helpers::current_town(); + if ($town === null) { + return $url; + } + $main = Helpers::main_town_slug(); + if ($main !== null && $town === $main) { + return $url; + } + if (!Helpers::is_routable_path($url)) { + return $url; + } + + $parsed = parse_url($url); + if ($parsed === false) { + return $url; + } + + // Path-only URL: no scheme and no host. + if (empty($parsed['scheme']) && empty($parsed['host'])) { + $path = $parsed['path'] ?? ''; + if (self::path_already_has_town_prefix($path, $town)) { + return $url; + } + $query = isset($parsed['query']) ? '?' . $parsed['query'] : ''; + $fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : ''; + return '/' . $town . $path . $query . $fragment; + } + + // Full URL with scheme: only http(s) on our own host. + $scheme = strtolower((string) ($parsed['scheme'] ?? '')); + if ($scheme !== 'http' && $scheme !== 'https') { + return $url; + } + + $host = $parsed['host'] ?? ''; + $current_host = $_SERVER['HTTP_HOST'] ?? ''; + if ($host === '' || $host !== $current_host) { + return $url; + } + + $path = $parsed['path'] ?? '/'; + if (self::path_already_has_town_prefix($path, $town)) { + return $url; + } + + $query = isset($parsed['query']) ? '?' . $parsed['query'] : ''; + $fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : ''; + return $scheme . '://' . $host . '/' . $town . $path . $query . $fragment; + } + + private static function path_already_has_town_prefix(string $path, string $town): bool + { + return $path === '/' . $town + || str_starts_with($path, '/' . $town . '/'); } }